{"record":{"id":"b05253f1defc7cb1","repo":"caddyserver/caddy","slug":"generating-and-storing-new-replacement-ech-config","errorCode":null,"errorMessage":"generating and storing new replacement ECH config: %w","messagePattern":"generating and storing new replacement ECH config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/ech.go","lineNumber":238,"sourceCode":"\t}\n\n\t// iterate the updated list and do any updates as needed\n\tfor publicName := range ech.configs {\n\t\tfor i := 0; i < len(ech.configs[publicName]); i++ {\n\t\t\tcfg := ech.configs[publicName][i]\n\t\t\tif time.Since(cfg.meta.Created) >= rotationInterval && cfg.meta.Replaced.IsZero() {\n\t\t\t\t// key is due for rotation and it hasn't been replaced yet; do that now\n\t\t\t\tlogger.Debug(\"ECH config is due for rotation\",\n\t\t\t\t\tzap.String(\"public_name\", cfg.RawPublicName),\n\t\t\t\t\tzap.Uint8(\"id\", cfg.ConfigID),\n\t\t\t\t\tzap.Time(\"created\", cfg.meta.Created),\n\t\t\t\t\tzap.Duration(\"age\", time.Since(cfg.meta.Created)),\n\t\t\t\t\tzap.Duration(\"rotation_interval\", rotationInterval))\n\n\t\t\t\t// start by generating and storing the replacement ECH config\n\t\t\t\tnewCfg, err := generateAndStoreECHConfig(ctx, publicName)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"generating and storing new replacement ECH config: %w\", err)\n\t\t\t\t}\n\n\t\t\t\t// mark the key as replaced so we don't rotate it again, and instead delete it later\n\t\t\t\tech.configs[publicName][i].meta.Replaced = time.Now()\n\n\t\t\t\t// persist the updated metadata\n\t\t\t\tmetaBytes, err := json.Marshal(ech.configs[publicName][i].meta)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"marshaling updated ECH config metadata: %v\", err)\n\t\t\t\t}\n\t\t\t\tif err := storage.Store(ctx, echMetaKey(cfg.ConfigID), metaBytes); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"storing updated ECH config metadata: %v\", err)\n\t\t\t\t}\n\n\t\t\t\tech.configs[publicName] = append(ech.configs[publicName], newCfg)\n\n\t\t\t\tlogger.Debug(\"rotated ECH key\",\n\t\t\t\t\tzap.String(\"public_name\", cfg.RawPublicName),","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/ech.go#L220-L256","documentation":"Error \"generating and storing new replacement ECH config: %w\" thrown in caddyserver/caddy.","triggerScenarios":"Thrown at modules/caddytls/ech.go:238 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the wrapped error; generating or storing the replacement ECH config failed, often a storage or RNG problem."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}