Laravel-Fehler „Unknown column ‚updated_at’“ beheben

Einleitung Das mit Laravel gelieferte Eloquent ORM gibt dir einen einfachen Weg, mit deiner Datenbank zu arbeiten. Es vereinfacht sämtliche CRUD-Operationen (Create, read, update, and delete) und jede weitere Datenbankabfrage. Laut der offiziellen Laravel-Dokumentation erwartet Eloquent, dass created_at und updated_at vorhanden sind

Laravel-Fehler „Unknown column ‘updated_at’“ beheben
Schnelle Antwort

Eloquent schreibt bei jedem Insert created_at und updated_at mit: Der Fehler bedeutet, dass die Tabelle diese Spalten nicht hat. Je nach Fall gibt es drei Korrekturen: Ergänze sie per Migration mit $table->timestamps(), schalte sie im Model mit public $timestamps = false; ab, oder deklariere ihre echten Namen über die Konstanten CREATED_AT und UPDATED_AT.

Die Meldung erscheint beim ersten save() oder create() auf einem Model:

code
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'INSERT INTO'

Die Ursache ist immer dieselbe: Eloquent pflegt zwei Datumsspalten, created_at und updated_at, und schreibt sie bei jedem Insert und jedem Update mit. Fehlen sie in der Tabelle, scheitert die Query. Es gibt drei Wege, das zu beheben, und der richtige hängt von der Tabelle ab, nicht von deinem Geschmack.

Erschienen im Themenpfad Webentwicklung. Fehler reproduziert und Korrekturen geprüft auf Laravel 13.30.1 mit MariaDB 11.8.9.

Den Fehler erkennen

Der Wortlaut hängt von der Datenbank und von der Operation ab, nennt aber immer updated_at oder created_at:

code
-- à l'insertion (MySQL / MariaDB)
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'INSERT INTO'

-- à la mise à jour
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'reports.updated_at' in 'SET'

-- sur SQLite
SQLSTATE[HY000]: General error: 1 table reports has no column named updated_at

Sieh zuerst nach, was in der Tabelle tatsächlich steht:

bash
php artisan tinker --execute='echo implode(", ", Schema::getColumnListing("reports"));'
code
id, title

Fehlen created_at und updated_at, lies weiter. Gibt es sie unter einem anderen Namen, spring direkt zur dritten Lösung.

Lösung 1: die Spalten ergänzen

Das vollständige Vorgehen beschreibt der Leitfaden zu den Laravel-Migrationen.

In den meisten Fällen ist das die richtige Antwort. Zu wissen, wann eine Zeile angelegt und wann sie geändert wurde, brauchst du früher oder später ohnehin, beim Debuggen wie beim Sortieren. Der Helper timestamps() legt beide Spalten auf einen Schlag an, nullable:

bash
php artisan make:migration add_timestamps_to_reports_table --table=reports
database/migrations/2026_09_02_000000_add_timestamps_to_reports_table.php
public function up(): void
{
    Schema::table('reports', function (Blueprint $table) {
        $table->timestamps();
    });
}

public function down(): void
{
    Schema::table('reports', function (Blueprint $table) {
        $table->dropTimestamps();
    });
}
bash
php artisan migrate

Nach der Migration läuft das Insert durch und die Daten stehen drin. Geprüft: Die Tabelle enthält id, title, created_at, updated_at, und $report->created_at liefert eine Instanz von Illuminate\Support\Carbon, die du formatieren und vergleichen kannst.

Enthält die Tabelle bereits Zeilen, werden die Spalten dort mit NULL angelegt, was unproblematisch ist. Willst du einen Wert, gibst du ihn explizit an:

php
$table->timestamp('created_at')->nullable()->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrent()->useCurrentOnUpdate();

Lösung 2: die Timestamps im Model abschalten

Soll die Tabelle diese Daten gar nicht führen, etwa eine Verknüpfungstabelle, feste Stammdaten oder ein von einem Fremdsystem vorgegebenes Schema, dann sag es dem Model:

app/Models/Video.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    public $timestamps = false;
}

Eloquent füllt die beiden Spalten daraufhin nicht mehr, und das Insert funktioniert. Bestätigen lässt sich der Zustand mit $video->usesTimestamps(), das false zurückgibt.

Dieselbe Abschaltung geht punktuell auf einer einzelnen Instanz, etwa um einen Wert zu korrigieren, ohne updated_at anzufassen:

php
$task->timestamps = false;
$task->title = 'Titre corrigé';
$task->save();   // updated_at bleibt unverändert
Schalte nicht ab, nur um den Fehler loszuwerden

Sollte die Tabelle diese Spalten eigentlich haben, löst $timestamps = false gar nichts: Es nimmt dir eine Information weg, die du später suchen wirst. Nimm diese Lösung nur für Tabellen, bei denen ein Änderungsdatum wirklich keinen Sinn ergibt.

Lösung 3: die Spalten heißen anders

In einer Altdatenbank heißen die Spalten oft date_creation, creation_date oder modified_on. Umbenennen musst du deshalb nichts: Nenne Eloquent über zwei Konstanten die echten Namen.

app/Models/Clip.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Clip extends Model
{
    const CREATED_AT = 'creation_date';
    const UPDATED_AT = 'updated_date';
}

Eloquent schreibt ab jetzt in diese Spalten. Geprüft auf Laravel 13: Nach Clip::create(['title' => 'Extrait']) steht der Zeitstempel in creation_date, und getUpdatedAtColumn() liefert updated_date.

Existiert nur eine der beiden Datumsspalten, setzt du die andere auf null:

php
const CREATED_AT = 'creation_date';
const UPDATED_AT = null;   // keine Spalte für die Aktualisierung

Die Accessoren $clip->created_at und $clip->updated_at folgen diesen Konstanten dagegen nicht: Sie liefern null. Lesen Sie die Spalte unter ihrem echten Namen, $clip->creation_date, oder generisch mit $clip->{$clip->getCreatedAtColumn()}.

Welche Lösung wann

Situation Lösung
Normale Anwendungstabelle, Spalten schlicht vergessen Spalten per Migration ergänzen
Pivot-Tabelle, feste Stammdaten, vorgegebenes Schema public $timestamps = false;
Altdatenbank mit anders benannten Datumsspalten Konstanten CREATED_AT und UPDATED_AT
Ein einzelner Schreibvorgang darf updated_at nicht anfassen $model->timestamps = false; vor save()

Häufige Fehler

Die Timestamps abschalten, nur um den Fehler loszuwerden Auf einer normalen Anwendungstabelle entfernt $timestamps = false eine nützliche Information, statt das Schema zu korrigieren. Ergänze lieber die Spalten.
NOT-NULL-Spalten auf einer bereits gefüllten Tabelle timestamps() legt sie nullable an, das läuft durch. Eine NOT-NULL-Definition ohne Standardwert würde die Migration scheitern lassen.
Die Spalten der Altdatenbank umbenennen Unnötig und riskant: Die Konstanten CREATED_AT und UPDATED_AT genügen, um auf die vorhandenen Namen zu zeigen.
UPDATED_AT = null vergessen Hat die Tabelle nur eine Spalte für das Anlegen, taucht beim Update derselbe Fehler wieder auf, wenn UPDATED_AT auf dem Standard bleibt.

EloquentLaravelMigrationsPHP

Damien Flandrin Webentwickler seit 2010, Gründer von Gekkode und Email Impact. Jeder Artikel wird vor der Veröffentlichung an einem echten Projekt getestet. Kontakt
Newsletter

Neue Tests, Tutorials und Projekte, per E-Mail.

Reproduzierbare Tests, versionierter Code, datierte Ergebnisse. Niemals Spam.