{"record":{"id":"5a519ead24b0b441","repo":"crowdsecurity/crowdsec","slug":"no-header-in-message-skipping","errorCode":null,"errorMessage":"no header in message, skipping","messagePattern":"no header in message, skipping","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/apiserver/papi.go","lineNumber":139,"sourceCode":"\t\tconsoleConfig: consoleConfig,\n\t\tLogger:        logger.WithFields(log.Fields{\"interval\": SyncInterval.Seconds(), \"source\": \"papi\"}),\n\t\tstopChan:      make(chan struct{}),\n\t}\n\n\treturn papi, nil\n}\n\nfunc (p *Papi) handleEvent(ctx context.Context, event longpollclient.Event, sync bool) error {\n\tlogger := p.Logger.WithField(\"request-id\", event.RequestId)\n\tlogger.Debugf(\"message received: %+v\", event.Data)\n\n\tmessage := &Message{}\n\tif err := json.Unmarshal([]byte(event.Data), message); err != nil {\n\t\treturn fmt.Errorf(\"polling papi message format is not compatible: %+v: %w\", event.Data, err)\n\t}\n\n\tif message.Header == nil {\n\t\treturn errors.New(\"no header in message, skipping\")\n\t}\n\n\tif message.Header.Source == nil {\n\t\treturn errors.New(\"no source user in header message, skipping\")\n\t}\n\n\toperationFunc, ok := operationMap[message.Header.OperationType]\n\tif !ok {\n\t\treturn fmt.Errorf(\"operation '%s' unknown, continue\", message.Header.OperationType)\n\t}\n\n\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)","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/papi.go#L121-L157","documentation":"The papi (push/pull notification channel) handler unmarshals each polled event into a Message struct. If the message carries no Header object, the handler cannot route it to an operation, so it returns this error and the message is skipped.","triggerScenarios":"PullOnce/Pull -> handleEvent when json.Unmarshal succeeds but message.Header is nil (event.Data lacks the expected header object).","commonSituations":"Upstream/remote peer sends malformed or version-incompatible payloads; non-crowdsec service posting to the same channel; partial/truncated messages from the publisher.","solutions":["Verify the sending side produces messages with the expected header object and operation_type","Check for version mismatch between the two CrowdSec instances and upgrade the sender","Inspect the raw event.Data logged around the error to identify the malformed source"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// sender-side: refuse to publish header-less messages\nif msg.Header == nil {\n    return errors.New(\"refusing to publish message without header\")\n}","typeGuard":null,"tryCatchPattern":"if err := p.handleEvent(ctx, event); err != nil {\n    log.WithError(err).Warnf(\"skipping papi event %s\", event.ID)\n    continue // non-fatal: bad message is skipped\n}","preventionTips":["Keep sender and receiver CrowdSec versions compatible","Validate the message schema on the publishing side","Log the raw payload when unmarshaled shape deviates"],"tags":["papi","json","polling","message"],"backgroundTag":"unexpected-api-response-shape","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"}