What is the BAD file format?
A .bad file is an Oracle SQL*Loader Bad File - a plain-text output file that SQL*Loader writes when it rejects rows during a bulk data load into an Oracle database.
The file contains a verbatim copy of every row that could not be loaded, in the same format as the original input (CSV, fixed-width, or stream). Because the content mirrors the source exactly, corrected rows can be fed straight back into sqlldr using the same .ctl control file without reformatting - making the .bad file a repair-and-retry artifact rather than merely an error log.
Records end up in the .bad file for three reasons:
- The row violates an Oracle constraint (duplicate unique key,
NOT NULLviolation, etc.). - SQL*Loader cannot parse field boundaries in a malformed delimited row.
- A field value cannot be converted to the target column's data type.
The .bad file is distinct from the .dsc discard file. Discards are rows intentionally skipped by a WHEN clause in the control file - they were never attempted. Bad records were attempted and failed.
If every input row loads successfully, the .bad file is not created at all. The default name derives from the input data file (e.g., data.csv → data.bad) unless overridden with BADFILE= in the control file or BAD= on the command line.
SQL*Loader has been part of Oracle Database since version 6 (1988) and remains a core utility in current Oracle Database 23ai releases.
Security & safety
RISK: LOWPlain text data file; cannot execute. May contain sensitive business data (PII, financial records) from a failed import - treat accordingly, restrict file system access to authorized DBAs and ETL operators.
Format details
in a nutshell- Microsoft Exchange Server bad-message file - Exchange SMTP transport stores undeliverable or malformed messages in .BAD files in the Exchange queue directory.
- General 'bad data' marker (various applications) - Some ETL tools and legacy programs use .bad as a generic extension for error/reject output files.
Programs that open BAD files
Technical details
deep spec| Format type | Plain-text rejected-row mirror (same structure as the SQL*Loader input datafile) |
| Encoding | Matches the input datafile - ASCII, UTF-8, or Oracle NLS character set as configured in the control file |
| Content | Verbatim copy of every row rejected during the SQL*Loader run, in original input format |
| Rejection reasons | Oracle constraint violation (PK/UK/NOT NULL); unparseable field delimiters; data-type conversion failure |
| LOB data handling | LOB content from LOBFILE or SDF sources is NOT written to the .bad file when its row is rejected |
| Default filename | <input_datafile_basename>.bad (e.g., data.csv → data.bad) |
| Filename override | BADFILE= in the .ctl control file, or BAD= on the sqlldr command line |
| File creation | Created only when at least one row is rejected; absent on completely successful loads |
| Distinction from .dsc | .dsc (discard) holds rows skipped by a WHEN clause - intentional skips, not errors; .bad holds rows that failed insertion |
| Re-use workflow | Corrected .bad file can be reloaded directly with the same .ctl control file without reformatting |
| Platform support | Any Oracle Database platform: Linux, Unix, Windows, Solaris, AIX |
| Released | Oracle 7 era, circa 1992 (SQL*Loader has existed since Oracle 6, 1988) |
| Latest version | N/A - format is defined by the input data format; no versioning |
| Specification | docs.oracle.com |
BAD conversions
Community Q&A
asked by usersNo questions yet - be the first to ask about BAD files.