{"record":{"id":"6b354efd6cab111d","repo":"crowdsecurity/crowdsec","slug":"while-parsing-bouncers-api-auto-delete-duration","errorCode":null,"errorMessage":"while parsing bouncers api auto-delete duration: %w","messagePattern":"while parsing bouncers api auto-delete duration: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/flush.go","lineNumber":105,"sourceCode":"\t\tif config.AgentsGC.Api != nil {\n\t\t\tc.Log.Warning(\"agents auto-delete for API auth is not supported (use cert or login_password)\")\n\t\t}\n\t}\n\n\tif config.BouncersGC != nil {\n\t\tif config.BouncersGC.Cert != nil {\n\t\t\tduration, err := cstime.ParseDurationWithDays(*config.BouncersGC.Cert)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"while parsing bouncers cert auto-delete duration: %w\", err)\n\t\t\t}\n\n\t\t\tconfig.BouncersGC.CertDuration = &duration\n\t\t}\n\n\t\tif config.BouncersGC.Api != nil {\n\t\t\tduration, err := cstime.ParseDurationWithDays(*config.BouncersGC.Api)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"while parsing bouncers api auto-delete duration: %w\", err)\n\t\t\t}\n\n\t\t\tconfig.BouncersGC.ApiDuration = &duration\n\t\t}\n\n\t\tif config.BouncersGC.LoginPassword != nil {\n\t\t\tc.Log.Warning(\"bouncers auto-delete for login/password auth is not supported (use cert or api)\")\n\t\t}\n\t}\n\n\t_, err = scheduler.NewJob(\n\t\tgocron.DurationJob(flushInterval),\n\t\tgocron.NewTask(c.FlushAgentsAndBouncers, ctx, config.AgentsGC, config.BouncersGC),\n\t\tgocron.WithSingletonMode(gocron.LimitModeReschedule),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while starting FlushAgentsAndBouncers scheduler: %w\", err)\n\t}","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/flush.go#L87-L123","documentation":"StartFlushScheduler parses bouncers_gc.api with cstime.ParseDurationWithDays to schedule deletion of bouncers authenticated via API keys. An unparseable duration string yields this wrapped error and stops startup.","triggerScenarios":"config.BouncersGC.Api holds a value ParseDurationWithDays cannot handle — unitless number, unknown suffix, or malformed duration.","commonSituations":"Config like api: 1mo under api.server.gc.bouncers_gc; trailing whitespace or stray characters in the YAML value.","solutions":["Fix the api key to a valid duration, e.g. api: 30d or api: 168h.","Use only supported units: Go duration units (ns..h) or 'd'.","Quote the YAML value to avoid parsing surprises, e.g. api: \"30d\".","Remove the key to disable bouncer API-key GC."],"exampleFix":"// before\nbouncers_gc:\n  api: 1mo\n\n// after\nbouncers_gc:\n  api: \"30d\"","handlingStrategy":"validation","validationCode":"if cfg.BouncersGC != nil && cfg.BouncersGC.Api != \"\" {\n    if _, err := cstime.ParseDurationWithDays(cfg.BouncersGC.Api); err != nil {\n        return fmt.Errorf(\"bouncers_gc.api: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"bouncers api\") {\n        // reject/fix the bouncers_gc.api value\n    }\n    return err\n}","preventionTips":["Quote YAML duration strings to prevent accidental numeric coercion (api: \"30d\").","Stick to supported units: Go durations or days.","Validate durations programmatically before writing generated configs."],"tags":["go","config","duration","crowdsec"],"backgroundTag":"invalid-duration-format","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}