{"record":{"id":"a969f0772fab41b2","repo":"iflytek/astron-agent","slug":"load-tenant-bootstrap-credentials-failed-w","errorCode":null,"errorMessage":"load tenant bootstrap credentials failed: %w","messagePattern":"load tenant bootstrap credentials failed: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/tenant/app/server.go","lineNumber":31,"sourceCode":"\n\t\"tenant/config\"\n\t\"tenant/internal/handler\"\n\t\"tenant/tools/generator\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc Run() error {\n\tconfigPath := flag.String(\"config\", \"./config/config.toml\", \"config file path\")\n\tflag.Parse()\n\tcfg, err := config.LoadConfig(*configPath)\n\tif err != nil {\n\t\tlog.Fatalf(\"config load failed: %s\\n\", err)\n\t\treturn err\n\t}\n\ttenantBootstrap, err := config.LoadTenantBootstrapCredentials()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"load tenant bootstrap credentials failed: %w\", err)\n\t}\n\tcfg.TenantBootstrap = tenantBootstrap\n\terr = initLog(cfg)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn runHttpServer(cfg)\n}\n\nfunc runHttpServer(cfg *config.Config) error {\n\tr := gin.New()\n\tgin.SetMode(gin.ReleaseMode)\n\tr.GET(\"/ping\", func(c *gin.Context) {\n\t\tc.JSON(http.StatusOK, gin.H{\"message\": \"pong\"})\n\t})\n\terr := handler.InitRouter(r, cfg)\n\tif err != nil {\n\t\tlog.Fatalf(\"init router failed: %s\\n\", err)","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/app/server.go#L13-L49","documentation":"Run loads tenant bootstrap credentials at server startup via config.LoadTenantBootstrapCredentials and wraps any failure as 'load tenant bootstrap credentials failed: %w'. This is a startup-fatal wrapper: the underlying error is a missing/invalid TENANT_KEY/TENANT_SECRET environment or file credential, or a Validate() failure.","triggerScenarios":"main → Run calls LoadTenantBootstrapCredentials, which fails because neither TENANT_KEY nor TENANT_KEY_FILE (or their SECRET counterparts) is set, the credential file cannot be read, or Validate() rejects the values.","commonSituations":"Deploying the tenant service without the Kubernetes Secret mounted into env; Helm values omitting TENANT_KEY/TENANT_SECRET; rotated credentials that violate length/character rules; TENANT_KEY_FILE pointing to a deleted or unreadable path.","solutions":["Read the wrapped cause (%w) in the error — it names the exact missing variable or validation failure.","Set TENANT_KEY and TENANT_SECRET env vars to 32-50 char ASCII values (or point TENANT_KEY_FILE/TENANT_SECRET_FILE at regular files).","If using file-based secrets, verify the files exist, are regular non-symlink files, are ≤4096 bytes, and are readable by the process.","Confirm TENANT_ID is unset or exactly \"680ab54f\" (BootstrapTenantID), since Validate rejects any other value."],"exampleFix":"// before (deployment env)\n# TENANT_KEY / TENANT_SECRET not set\n\n// after\nenv:\n  - name: TENANT_KEY\n    valueFrom: { secretKeyRef: { name: tenant-bootstrap, key: tenant-key } }\n  - name: TENANT_SECRET\n    valueFrom: { secretKeyRef: { name: tenant-bootstrap, key: tenant-secret } }","handlingStrategy":"try-catch","validationCode":"for _, k := range []string{\"TENANT_KEY\", \"TENANT_KEY_FILE\", \"TENANT_SECRET\", \"TENANT_SECRET_FILE\"} {\n\tif os.Getenv(k) == \"\" { log.Printf(\"warning: %s not set\", k) }\n}","typeGuard":null,"tryCatchPattern":"if err := Run(); err != nil {\n\tlog.Fatalf(\"tenant server exited: %v\", err) // inspect wrapped cause with %v / errors.Unwrap\n}","preventionTips":["Document required TENANT_* env vars in the Helm chart values and README.","Add a readiness/liveness-impacting preflight that fails deployment early with a clear message.","Keep secrets in a versioned Secret manifest so they are never omitted during rollouts."],"tags":["config","credentials","startup","go"],"backgroundTag":"missing-credentials","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}