juanfont/headscale · critical
adding description to pre_auth_keys: %w
Error message
adding description to pre_auth_keys: %w
What it means
Migration '202606191501-pre-auth-key-description' fails adding the free-text description column to pre_auth_keys (HasColumn-guarded AddColumn) for the v2 keys API. Identical failure class to the other AddColumn migrations: ALTER privilege missing, database locked, disk full, or drifted schema confusing the guard.
Source
Thrown at hscontrol/db/db.go:809
err := tx.Migrator().AddColumn(&types.APIKey{}, "user_id")
if err != nil {
return fmt.Errorf("adding user_id to api_keys: %w", err)
}
}
return nil
},
Rollback: func(db *gorm.DB) error { return nil },
},
{
// Add a free-text description to pre-auth keys, set via the
// v2 keys API.
ID: "202606191501-pre-auth-key-description",
Migrate: func(tx *gorm.DB) error {
if !tx.Migrator().HasColumn(&types.PreAuthKey{}, "description") {
err := tx.Migrator().AddColumn(&types.PreAuthKey{}, "description")
if err != nil {
return fmt.Errorf("adding description to pre_auth_keys: %w", err)
}
}
return nil
},
Rollback: func(db *gorm.DB) error { return nil },
},
{
// Add a revoked timestamp to pre-auth keys. The v2 API's DELETE
// soft-revokes a key (set revoked = now) rather than destroying
// it; the row is reaped later by the background collector.
ID: "202606201200-pre-auth-key-revoked",
Migrate: func(tx *gorm.DB) error {
if !tx.Migrator().HasColumn(&types.PreAuthKey{}, "revoked") {
err := tx.Migrator().AddColumn(&types.PreAuthKey{}, "revoked")
if err != nil {
return fmt.Errorf("adding revoked to pre_auth_keys: %w", err)
}View on GitHub (pinned to 565fd254d0)
Solutions
- Resolve the wrapped underlying error (privileges / locks / disk)
- Pre-apply ALTER TABLE pre_auth_keys ADD COLUMN description text DEFAULT '' if drift makes AddColumn fail, then restart - the HasColumn guard makes re-runs safe
- Confirm the column post-startup with \d pre_auth_keys or PRAGMA table_info(pre_auth_keys)
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the database accepts DDL before the upgrade window
if _, err := db.Exec("CREATE TEMP TABLE _p(id integer)"); err != nil {
log.Fatalf("database not DDL-writable: %v", err)
} Prevention
- Same hygiene as all AddColumn migrations: backup, single instance, DDL rights
- Avoid mounting the SQLite file read-only in containers
When it happens
Trigger: Startup migration on a schema without pre_auth_keys.description while DDL execution is blocked or unauthorized.
Common situations: Upgrading alongside the v2 API rollout; constrained DB roles; shared SQLite databases; read-only database mounts.
Related errors
- creating prefix index: %w
- adding user_id to api_keys: %w
- adding revoked to pre_auth_keys: %w
- automigrating types.Route: %w
- automigrating types.PreAuthKey: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/617f4da2b8c6b42b.
Report an issue: GitHub.