iflytek/astron-agent · critical
load tenant bootstrap credentials failed
Error message
load tenant bootstrap credentials failed: %w
What it means
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.
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.
Example fix
// before (deployment env)
# TENANT_KEY / TENANT_SECRET not set
// after
env:
- name: TENANT_KEY
valueFrom: { secretKeyRef: { name: tenant-bootstrap, key: tenant-key } }
- name: TENANT_SECRET
valueFrom: { secretKeyRef: { name: tenant-bootstrap, key: tenant-secret } } Defensive patterns
Strategy: try-catch
Validate before calling
for _, k := range []string{"TENANT_KEY", "TENANT_KEY_FILE", "TENANT_SECRET", "TENANT_SECRET_FILE"} {
if os.Getenv(k) == "" { log.Printf("warning: %s not set", k) }
} Try / catch
if err := Run(); err != nil {
log.Fatalf("tenant server exited: %v", err) // inspect wrapped cause with %v / errors.Unwrap
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- database config is nil or dbType is empty
- TENANT_ID must remain
- or is required
- invalid tenant bootstrap credentials
- WORKFLOW_INTERNAL_API_KEY must contain a non-default value…
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/a969f0772fab41b2.
Report an issue: GitHub.
Appendix: source
Thrown at core/tenant/app/server.go:31
"tenant/config"
"tenant/internal/handler"
"tenant/tools/generator"
"github.com/gin-gonic/gin"
)
func Run() error {
configPath := flag.String("config", "./config/config.toml", "config file path")
flag.Parse()
cfg, err := config.LoadConfig(*configPath)
if err != nil {
log.Fatalf("config load failed: %s\n", err)
return err
}
tenantBootstrap, err := config.LoadTenantBootstrapCredentials()
if err != nil {
return fmt.Errorf("load tenant bootstrap credentials failed: %w", err)
}
cfg.TenantBootstrap = tenantBootstrap
err = initLog(cfg)
if err != nil {
return err
}
return runHttpServer(cfg)
}
func runHttpServer(cfg *config.Config) error {
r := gin.New()
gin.SetMode(gin.ReleaseMode)
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "pong"})
})
err := handler.InitRouter(r, cfg)
if err != nil {
log.Fatalf("init router failed: %s\n", err)View on GitHub (pinned to 5e758547a8)