Databricks Auto Loader infers a schema by sampling the first files it reads, stores it in cloudFiles.schemaLocation, and decides what to do when a new column arrives through cloudFiles.schemaEvolutionMode. The default, addNewColumns, records the new column and stops the stream once so that a restart picks it up.
Last updated October 2026.
Chapter 7 of the course covers what Auto Loader is: the cloudFiles source, file discovery, the checkpoint and the idea of schema evolution. This post is the reference behind that card: a full pipeline, every option it uses, the five evolution modes side by side, and what lands in _rescued_data.
Auto Loader sits in Data Ingestion and Loading, the second of the seven sections in the May 2026 version of the Databricks Certified Data Engineer Associate exam. Questions usually describe a pipeline that broke, or did not break, when the files changed shape.
checkpoint = "/Volumes/main/bronze/checkpoints/events"
(spark.readStream
.format("cloudFiles")
.option("cloudFiles.format", "json")
.option("cloudFiles.schemaLocation", checkpoint)
.option("cloudFiles.inferColumnTypes", "true")
.option("cloudFiles.schemaHints", "event_ts timestamp, amount decimal(10,2)")
.load("/Volumes/main/landing/events/")
.writeStream
.option("checkpointLocation", checkpoint)
.option("mergeSchema", "true")
.trigger(availableNow=True)
.toTable("main.bronze.events"))
| Line | What it does |
|---|---|
format("cloudFiles") | Selects Auto Loader as the streaming source. |
cloudFiles.format | The file type being read: json, csv, xml, parquet, avro, text, binaryFile and others. |
cloudFiles.schemaLocation | Where the inferred schema, and every later version of it, is stored. It can be the same path as the checkpoint. Without it, inference and evolution are off. |
cloudFiles.inferColumnTypes | Infers real types for JSON, CSV and XML. Without it every column comes back as a string. |
cloudFiles.schemaHints | Pins the types of columns you already know, in SQL schema syntax. |
checkpointLocation | Records which files were processed, so a restart resumes exactly where it stopped. |
mergeSchema | Lets the Delta target accept the columns Auto Loader adds. The Databricks schema evolution examples pair it with Auto Loader on the write. |
trigger(availableNow=True) | Processes every file that is waiting, then stops: batch scheduling with streaming bookkeeping. |
On the first run Auto Loader samples up to 50 GB or 1,000 files, whichever limit it reaches first, and writes the result to a _schemas directory under the schema location. Later runs read the stored schema instead of sampling again, which is why the schema location is required.
cloudFiles.inferColumnTypes to true to get real types instead..option("header", "false").abc, Abc and ABC are treated as one column during inference..option("cloudFiles.schemaHints", "tags map<string,string>, version int")
A hint overrides the inferred type of one column and leaves the rest to inference. Hints can also name a column that has not appeared yet, so it exists with the right type from the first batch. They apply only when you have not supplied a full schema with .schema(...), and they work with inferColumnTypes on or off.
This is the part the exam tests. cloudFiles.schemaEvolutionMode takes one of five values:
| Mode | On a new column | Stream |
|---|---|---|
addNewColumns | Adds it to the end of the schema in the schema location. Existing column types never change. | Stops once with UnknownFieldException; the restart uses the new schema. Default when no schema is supplied. |
addNewColumnsWithTypeWidening | As addNewColumns, and also widens supported types (int to long). Unsupported changes, such as int to string, go to the rescued data column. | Stops once, like addNewColumns. Public Preview on Databricks Runtime 16.4 and above. |
rescue | Never changes the schema. The new column's values go to the rescued data column. | Keeps running. |
failOnNewColumns | Changes nothing. | Fails and stays failed until you update the schema or remove the file. |
none | Ignores the new column. Its data is dropped unless rescuedDataColumn is set. | Keeps running. Default when you supply a schema. |
Sourced from the Databricks documentation page "Configure schema inference and evolution in Auto Loader".
With addNewColumns, Auto Loader runs inference on the latest micro-batch, appends the new columns to the stored schema and then fails the stream. A running stream cannot change its schema in place, so the failure is how the new version takes effect. Databricks recommends running the stream as a Lakeflow Job, whose retry restarts it without anyone stepping in. A question that says "the stream failed after the files gained a field, and succeeded on retry" is describing exactly this.
(spark.readStream
.format("cloudFiles")
.option("cloudFiles.format", "json")
.schema("id bigint, event_ts timestamp, amount decimal(10,2)")
.option("rescuedDataColumn", "_rescued_data")
.load("/Volumes/main/landing/events/"))
With .schema(...) the default mode becomes none, and addNewColumns is not allowed at all. The line above adds the rescued data column explicitly, so unexpected fields are kept rather than silently dropped. If you want evolution with known types, use schema hints instead of a full schema.
When inference is on, Auto Loader adds a _rescued_data column. Instead of failing or dropping a record that does not fit the schema, it stores the parts that did not fit as a JSON string, together with the path of the file they came from. Three things end up there:
"twelve" in an int column;Amount against amount.SELECT _rescued_data, count(*) AS records
FROM main.bronze.events
WHERE _rescued_data IS NOT NULL
GROUP BY _rescued_data;
A query like this in Silver is the usual way to notice drift without stopping Bronze. The column also changes how parser modes behave: with it set, a type mismatch no longer drops a record in DROPMALFORMED or fails the read in FAILFAST. Only records that are actually corrupt do.
event=click/date=2026-10-01/, but a new directory key is not picked up automatically. List the keys in cloudFiles.partitionColumns, for example "event,date".cloudFiles.schemaLocation yourself.Exam tip: "absorb new columns" points at the default addNewColumns, and "the stream stopped once, then ran" is that mode working as designed. "Never stop, keep unexpected fields for later" is rescue. "Fail loudly on any change" is failOnNewColumns. "A schema was supplied and the new field vanished" is none, the default with a supplied schema.
A common distractor puts schema handling on the checkpoint or on file notification mode. The checkpoint tracks which files were processed, and file notification only changes how new files are found. Neither touches the schema. When to choose Auto Loader over COPY INTO at all is covered in the COPY INTO vs Auto Loader post and in Chapter 8 of the course.
The default is addNewColumns when you do not supply a schema, and none when you do. With addNewColumns the stream stops once on a new column, records it in the schema location, and picks it up on restart.
That failure is how addNewColumns applies a new column: Auto Loader has already saved the updated schema, and the next run uses it. Run the stream as a Lakeflow Job with retries so the restart happens automatically.
Data that did not fit the schema: fields missing from it, values with the wrong type, and fields whose case differs. It is stored as a JSON string with the source file path, so nothing is silently lost.
Strings never fail to parse, so a value that changes type between files cannot break the stream. Set cloudFiles.inferColumnTypes to true for real types, or pin specific columns with cloudFiles.schemaHints.
Auto Loader is Chapter 7 of the Databricks Data Engineer Associate course, in Unit 2, Data Ingestion and Loading, with the source, discovery and checkpoint built up card by card and exam-style checks.
Open Chapter 7 →