{"record":{"id":"dea909c58f248e19","repo":"caddyserver/caddy","slug":"stek-gob-corrupted-v","errorCode":null,"errorMessage":"STEK gob corrupted: %v","messagePattern":"STEK gob corrupted: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"modules/caddytls/distributedstek/distributedstek.go","lineNumber":128,"sourceCode":"}\n\n// Next returns a channel which transmits the latest session ticket keys.\nfunc (s *Provider) Next(doneChan <-chan struct{}) <-chan [][32]byte {\n\tkeysChan := make(chan [][32]byte)\n\tgo s.rotate(doneChan, keysChan)\n\treturn keysChan\n}\n\nfunc (s *Provider) loadSTEK() (distributedSTEK, error) {\n\tvar sg distributedSTEK\n\tgobBytes, err := s.storage.Load(s.ctx, stekFileName)\n\tif err != nil {\n\t\treturn sg, err // don't wrap, in case error is certmagic.ErrNotExist\n\t}\n\tdec := gob.NewDecoder(bytes.NewReader(gobBytes))\n\terr = dec.Decode(&sg)\n\tif err != nil {\n\t\treturn sg, fmt.Errorf(\"STEK gob corrupted: %v\", err)\n\t}\n\treturn sg, nil\n}\n\nfunc (s *Provider) storeSTEK(dstek distributedSTEK) error {\n\tvar buf bytes.Buffer\n\terr := gob.NewEncoder(&buf).Encode(dstek)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"encoding STEK gob: %v\", err)\n\t}\n\terr = s.storage.Store(s.ctx, stekFileName, buf.Bytes())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"storing STEK gob: %v\", err)\n\t}\n\treturn nil\n}\n\n// getSTEK locks and loads the current STEK from storage. If none","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/distributedstek/distributedstek.go#L110-L146","documentation":"The distributed STEK provider persists session ticket keys to storage as a gob; loadSTEK gob-decodes the stored bytes and wraps decode failures as 'STEK gob corrupted'. Notably, a storage read error (including not-exist) is NOT wrapped, so this specifically means bytes existed but did not decode — corruption or an incompatible gob schema.","triggerScenarios":"The stored stek file was truncated (e.g. crash during write), partially synced, or written by a different Caddy version whose distributedSTEK struct changed; manual tampering with the storage object.","commonSituations":"Crash or disk-full during a previous STEK write; upgrading Caddy across incompatible struct changes; copying storage buckets between environments mid-write.","solutions":["Delete the stored STEK object so a fresh key set is generated (the provider creates and persists new STEKs when none exists); for file storage remove the stek file under the storage root, then reload","If it recurs, check storage durability (disk health, fsync behavior, network storage consistency)","After a Caddy upgrade causing schema mismatch, a one-time deletion is expected and safe — old ticket keys are ephemeral by design"],"exampleFix":"# before: recurring 'STEK gob corrupted' at startup\nls /var/lib/caddy/storage/... # locate stek object\n\n# after: remove it and reload Caddy\nrm /var/lib/caddy/storage/<...>/stek  # path per your storage config\nsystemctl reload caddy","handlingStrategy":"fallback","validationCode":"// Detect a corrupt STEK object before it breaks the provider\ntype distributedSTEK struct { Keys [][32]byte; NextRotation time.Time }\nfunc stekLooksValid(b []byte) bool {\n\tvar s struct { Keys [][32]byte; NextRotation time.Time }\n\treturn gob.NewDecoder(bytes.NewReader(b)).Decode(&s) == nil && len(s.Keys) > 0\n}","typeGuard":null,"tryCatchPattern":"// Since loadSTEK does not wrap storage.ErrNotExist, treat decode failure as stale:\n// delete the stored object so the provider mints fresh keys on next rotation.\n// (shell)\nrm \"$CADDY_STORAGE_ROOT/.../stek\" && systemctl reload caddy","preventionTips":["Treat STEK objects as disposable cache — safe to delete after upgrades","Use durable storage backends with atomic writes (certmagic file storage already rename-writes)","Monitor for recurring corruption: it signals disk or storage-plugin faults"],"tags":["tls","stek","gob","storage","corruption"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}