{"record":{"id":"ff4abf9d449faf45","repo":"crowdsecurity/crowdsec","slug":"longpoll-api-error-message-s","errorCode":null,"errorMessage":"longpoll API error message: %s","messagePattern":"longpoll API error message: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/longpollclient/client.go","lineNumber":139,"sourceCode":"\t\tdefault:\n\t\t\tvar pollResp pollResponse\n\t\t\terr = decoder.Decode(&pollResp)\n\t\t\tif err != nil {\n\t\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t\tlogger.Debugf(\"server closed connection\")\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"error decoding poll response: %v\", err)\n\t\t\t}\n\n\t\t\tlogger.Tracef(\"got response: %+v\", pollResp)\n\n\t\t\tif pollResp.ErrorMessage != \"\" {\n\t\t\t\tif pollResp.ErrorMessage == timeoutMessage {\n\t\t\t\t\tlogger.Debugf(\"got timeout message\")\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"longpoll API error message: %s\", pollResp.ErrorMessage)\n\t\t\t}\n\n\t\t\tif len(pollResp.Events) > 0 {\n\t\t\t\tlogger.Debugf(\"got %d events\", len(pollResp.Events))\n\t\t\t\tfor _, event := range pollResp.Events {\n\t\t\t\t\tevent.RequestId = requestId\n\t\t\t\t\tc.c <- event\n\t\t\t\t\tif event.Timestamp > c.since {\n\t\t\t\t\t\tc.since = event.Timestamp\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif pollResp.Timestamp > 0 {\n\t\t\t\tc.since = pollResp.Timestamp\n\t\t\t}\n\t\t\tlogger.Debugf(\"Since is now %d\", c.since)\n\t\t}\n\t}","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/longpollclient/client.go#L121-L157","documentation":"The long-poll server answered successfully, but the decoded response carried a non-empty ErrorMessage field that is not the special timeout sentinel (\"no events before timeout\"). The client turns that server-side message into a Go error so the caller (pollEvents) treats it as a poll failure.","triggerScenarios":"poll() decodes a pollResp whose ErrorMessage is non-empty and != timeoutMessage; e.g. the LAPI rejected the request parameters or reported an internal error while producing the response.","commonSituations":"Requesting events with a filter/last-date the LAPI cannot honor; LAPI internal error during decision lookup; using a bouncer with parameters unsupported by the server version.","solutions":["Read the %s payload — it is the server's own error text; fix the request or server condition it describes.","Verify the client's query parameters (channel/filters/since) are valid for the connected LAPI version.","Check LAPI server logs for the matching error at the same timestamp.","Ensure auth is valid — some server errors stem from expired/insufficient bouncer credentials."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// before polling, sanity-check request params\nif lastDate != \"\" {\n    if _, err := time.Parse(time.RFC3339, lastDate); err != nil {\n        return fmt.Errorf(\"invalid last-date filter: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"// surface the server's own message to operators\nif err := client.Poll(); err != nil {\n    var apiErr string\n    if strings.Contains(err.Error(), \"longpoll API error message:\") {\n        fmt.Sscanf(err.Error(), \"longpoll API error message: %s\", &apiErr)\n        logger.Errorf(\"LAPI rejected poll: %s\", apiErr)\n    }\n    return err\n}","preventionTips":["Validate query parameters (channels, filters, since) against the LAPI version in use.","Keep bouncer credentials valid and renewed.","Watch LAPI server logs alongside client errors."],"tags":["longpoll","server-error","crowdsec-lapi"],"backgroundTag":"api-error-response","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"}