pingcap / pingcap/tidb

local_infile=OFF is accepted and reported but LOAD DATA LOCAL INFILE still succeeds

Open
#70,987 2 comments 0 reactions 0 assignees View on GitHub
affects-25.10 affects-26.3 affects-7.5 affects-8.1 affects-8.5 affects-9.0 component/server found-by-ai severity/major sig/sql-infra type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

```sql
-- MySQL 8.3 control:
SET GLOBAL local_infile=OFF;
-- client: mysql --local-infile=1
LOAD DATA LOCAL INFILE '/tmp/local.csv' INTO TABLE t
FIELDS TERMINATED BY ',';
-- ERROR 3948 (42000): Loading local data is disabled; this must be enabled
-- on both the client and server sides

-- TiDB a514:
SET GLOBAL local_infile=OFF;
SHOW GLOBAL VARIABLES LIKE 'local_infile'; -- OFF
-- client: mysql --local-infile=1
LOAD DATA LOCAL INFILE '/tmp/local.csv' INTO TABLE t
FIELDS TERMINATED BY ',';
SELECT a,b FROM t ORDER BY a; -- 1,x and 2,y
SHOW WARNINGS; -- empty
```

Probe output:

```text
MYSQL_LOCAL_INFILE_VARIABLE=local_infile\tOFF
MYSQL_LOAD_RC=1
MYSQL_LOAD_ERR=ERROR 3948 ... Loading local data is disabled ...
MYSQL_LOCAL_INFILE_DISABLED

TIDB_LOCAL_INFILE_VARIABLE=local_infile\tOFF
TIDB_LOAD_RC=0
TIDB_LOAD_OUT=['1\tx', '2\ty']
TIDB_LOCAL_INFILE_IGNORED
```

### 2. What did you expect to see? (Required)

When the server `local_infile` variable is `OFF`, `LOAD DATA LOCAL INFILE` must fail with MySQL error 3948 (or an equivalent explicit error) and import zero rows. The client-side `--local-infile=1` only enables the client half; the server must still enforce its own setting. If TiDB does not support disabling local infile, `SET GLOBAL local_infile=OFF` must fail instead of reporting `OFF`.

### 3. What did you see instead (Required)

TiDB: SET GLOBAL local_infile=OFF; SHOW GLOBAL VARIABLES -> OFF; mysql --local-infile=1 LOAD DATA LOCAL INFILE -> success, rows (1,x),(2,y). MySQL 8.3 control: local_infile=OFF -> ERROR 3948, zero rows.

### 4. What is your TiDB version? (Required)

```text
Release Version: v8.4.0-this-is-a-placeholder
Edition: Community
Git Commit Hash: None
Git Branch: None
UTC Build Time: None
GoVersion: go1.25.12
Race Enabled: false
Check Table Before Drop: false
Store: unistore
Kernel Type: Classic
```

Built from source commit `a514a92784c9654502686e6ee6efc9e0aeda8afa` (pingcap/tidb master, 2026-09-07).

### 5. Root cause (optional)

- pkg/sessionctx/variable/noop.go:544 registers local_infile as a noop global variable
- pkg/server/conn.go:1788-1799 writeReq sends LocalInFileHeader without checking local_infile
- no server-side local_infile consumer was found

Contributor guide

Open the contributing guide

Research direction

Start with pkg/sessionctx/variable/noop.go:544, where local_infile is registered, and pkg/server/conn.go:1788-1799, where the LocalInFileHeader is written. Reproduce the issue using the SQL and mysql client commands in the report, then trace how the server setting reaches LOAD DATA LOCAL INFILE handling. Done means OFF is enforced with an explicit error and zero imported rows, or disabling the setting fails if unsupported.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, mysql
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.