{"record":{"id":"dba45f52ac529065","repo":"pinpoint-apm/pinpoint","slug":"eventidentifier-cannot-be-less-than-0","errorCode":null,"errorMessage":"eventIdentifier cannot be less than 0","messagePattern":"eventIdentifier cannot be less than 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AgentLifeCycleBo.java","lineNumber":51,"sourceCode":"\n    private final byte version;\n    @NonNull\n    private final String agentId;\n    private final long startTimestamp;\n    private final long eventTimestamp;\n    private final long eventIdentifier;\n    private final AgentLifeCycleState agentLifeCycleState;\n    \n    public AgentLifeCycleBo(String agentId, long startTimestamp, long eventTimestamp, long eventIdentifier, AgentLifeCycleState agentLifeCycleState) {\n        this(CURRENT_VERSION, agentId, startTimestamp, eventTimestamp, eventIdentifier, agentLifeCycleState);\n    }\n\n    public AgentLifeCycleBo(int version, String agentId, long startTimestamp, long eventTimestamp, long eventIdentifier, AgentLifeCycleState agentLifeCycleState) {\n        this.version = ByteUtils.toUnsignedByte(version);\n        this.agentId = StringPrecondition.requireHasLength(agentId, \"agentId\");\n\n        if (eventIdentifier < 0) {\n            throw new IllegalArgumentException(\"eventIdentifier cannot be less than 0\");\n        }\n        this.startTimestamp = NumberPrecondition.requirePositiveOrZero(startTimestamp, \"startTimestamp\");\n        this.eventTimestamp = NumberPrecondition.requirePositiveOrZero(eventTimestamp, \"eventTimestamp\");\n        this.eventIdentifier = eventIdentifier;\n        this.agentLifeCycleState = Objects.requireNonNull(agentLifeCycleState, \"agentLifeCycleState\");\n    }\n\n    public int getVersion() {\n        return Byte.toUnsignedInt(this.version);\n    }\n\n    public String getAgentId() {\n        return agentId;\n    }\n\n    public long getStartTimestamp() {\n        return startTimestamp;\n    }","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/AgentLifeCycleBo.java#L33-L69","documentation":"AgentLifeCycleBo's constructor validates that the eventIdentifier (the agent's startTimestamp, used as a unique lifecycle event key) is non-negative before persisting the lifecycle event to HBase. A negative value means corrupted or mis-decoded input, so the library refuses to build the business object. This is an eager fail-fast guard on data integrity.","triggerScenarios":"Calling new AgentLifeCycleBo(version, agentId, startTimestamp, eventTimestamp, eventIdentifier, state) with a negative eventIdentifier, e.g. when deserializing a row key or agent-start timestamp that was decoded incorrectly or is corrupt.","commonSituations":"Corrupt or truncated HBase row keys, wrong endOffset/limit when slicing the agent-start-timestamp bytes out of a key, or agents from buggy collectors writing malformed timestamps.","solutions":["Check the caller that computes eventIdentifier (usually the agent startTimestamp extracted from a row key) and fix the byte-decoding offset/length","Log the raw input bytes/value before constructing AgentLifeCycleBo to find where the negative value originates","If the value can legitimately be 0, pass 0 rather than a negative sentinel; the constructor accepts 0","Reject the record upstream instead of constructing the BO so the error is handled where the data was read"],"exampleFix":"// before\nlong eventIdentifier = BufferFactory.resolve(rowKey.slice(0, 8)).readLong(); // misaligned -> negative\nnew AgentLifeCycleBo(version, agentId, start, event, eventIdentifier, state);\n// after\nlong eventIdentifier = new FixedBuffer(rowKey).readLong();\nif (eventIdentifier < 0) { log.warn(\"bad eventIdentifier {}\", eventIdentifier); return; }\nnew AgentLifeCycleBo(version, agentId, start, event, eventIdentifier, state);","handlingStrategy":"validation","validationCode":"if (eventIdentifier < 0) { log.warn(\"invalid eventIdentifier {} for agent {}\", eventIdentifier, agentId); return; }","typeGuard":"boolean isValidEventIdentifier(long v) { return v >= 0; }","tryCatchPattern":"try { new AgentLifeCycleBo(v, id, st, et, eid, state); } catch (IllegalArgumentException e) { log.warn(\"skipping lifecycle event: {}\", e.getMessage()); }","preventionTips":["Validate row-key decoding offsets before extracting the start timestamp","Log raw bytes when deserializing agent lifecycle events","Never use negative sentinel values for timestamps"],"tags":["java","data-integrity","validation","hbase"],"backgroundTag":"invalid-argument-value","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}