{"record":{"id":"332dfca08137b539","repo":"crowdsecurity/crowdsec","slug":"failed-to-create-request-w","errorCode":null,"errorMessage":"failed to create request: %w","messagePattern":"failed to create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiserver/papi.go","lineNumber":169,"sourceCode":"\tmetrics.PapiOrdersReceived.WithLabelValues(message.Header.OperationType, message.Header.OperationCmd).Inc()\n\n\tlogger.Debugf(\"Calling operation '%s'\", message.Header.OperationType)\n\n\terr := operationFunc(ctx, message, p, sync)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"'%s %s failed: %w\", message.Header.OperationType, message.Header.OperationCmd, err)\n\t}\n\n\treturn nil\n}\n\nfunc (p *Papi) GetPermissions(ctx context.Context) (PapiPermCheckSuccess, error) {\n\thttpClient := p.apiClient.GetClient()\n\tpapiCheckURL := fmt.Sprintf(\"%s%s%s\", p.URL, PAPIVersion, PAPIPermissionsURL)\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, papiCheckURL, http.NoBody)\n\tif err != nil {\n\t\treturn PapiPermCheckSuccess{}, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\tresp, err := httpClient.Do(req)\n\tif err != nil {\n\t\treturn PapiPermCheckSuccess{}, fmt.Errorf(\"failed to get response: %w\", err)\n\t}\n\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\terrResp := PapiPermCheckError{}\n\n\t\terr = json.NewDecoder(resp.Body).Decode(&errResp)\n\t\tif err != nil {\n\t\t\treturn PapiPermCheckSuccess{}, fmt.Errorf(\"failed to decode response: %w\", err)\n\t\t}\n\n\t\treturn PapiPermCheckSuccess{}, fmt.Errorf(\"unable to query PAPI : %s (%d)\", errResp.Error, resp.StatusCode)","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/papi.go#L151-L187","documentation":"GetPermissions queries the PAPI /permissions endpoint to check the console's subscription plan and permission categories. This error is returned when http.NewRequestWithContext fails to build the GET request — essentially only from an invalid URL composition (p.URL + PAPIVersion + PAPIPermissionsURL) such as a control character or unparseable scheme/host. The permission check aborts and no HTTP call is attempted.","triggerScenarios":"Called at PAPI startup / query flows (QueryPAPIInfo) when p.URL (derived from api.client.papi_url) yields a URL that http.NewRequestWithContext rejects — e.g. missing scheme or invalid characters in the configured papi URL.","commonSituations":"Hand-edited papi_url in config.yaml with a typo or missing scheme; environment-injected URL with trailing whitespace/newline; copy-paste of the base URL with quotes.","solutions":["Inspect api.client.papi_url in config.yaml for typos, missing https:// scheme, stray spaces or quotes.","Validate config with `crowdsec -t` after fixing.","Test the composed URL manually: <papi_url>v1/permissions should be syntactically valid in a browser/curl.","If unset, restore the default papi_url (https://api.crowdsec.net/)."],"exampleFix":"// before (config.yaml)\napi:\n  client:\n    papi_url: \"https://api.crowdsec.net/ \"\n// after\napi:\n  client:\n    papi_url: https://api.crowdsec.net/","handlingStrategy":"validation","validationCode":"u, err := url.Parse(papiBaseURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid papi url %q\", papiBaseURL)\n}","typeGuard":null,"tryCatchPattern":"perms, err := papi.GetPermissions(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to create request\") {\n        // configuration-level URL problem: do not retry, fix config\n        return fmt.Errorf(\"check api.client.papi_url: %w\", err)\n    }\n}","preventionTips":["Validate papi_url with a URL parser at config load time.","Trim whitespace/quotes from URL values loaded from env or templates.","Run config tests (`crowdsec -t`) in CI for deployed crowdsec configurations.","Keep papi_url at the upstream default unless support directs otherwise."],"tags":["papi","http","config","url"],"backgroundTag":"invalid-url-format","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}