pinpoint-apm/pinpoint · error · OracleConnectionStringException
parse error. token is null. Expected token='='
Error message
parse error. token is null. Expected token='='
What it means
checkEqualToken() consumes the token expected between a key and its value; when nextToken() returns null because the stream ended right after a key, it throws 'parse error. token is null. Expected token='='. The descriptor ended immediately after a key name with no '=' or value.
Source
Thrown at agent-module/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/parser/OracleNetConnectionDescriptorTokenizer.java:194
public void setPosition(int position) {
this.position = position;
}
public void checkStartToken() {
Token token = this.nextToken();
if (token == null) {
throw new OracleConnectionStringException("parse error. token is null");
}
// We can check by == because the token object is singleton.
if (!(token == TOKEN_KEY_START_OBJECT)) {
throw new OracleConnectionStringException("syntax error. Expected token='(' :" + token.getToken());
}
}
public void checkEqualToken() {
Token token = this.nextToken();
if (token == null) {
throw new OracleConnectionStringException("parse error. token is null. Expected token='='");
}
// We can check by == because the token object is singleton.
if (!(token == TOKEN_EQUAL_OBJECT)) {
throw new OracleConnectionStringException("Syntax error. Expected token='=' :" + token.getToken());
}
}
public void checkEndToken() {
Token token = this.nextToken();
if (token == null) {
throw new OracleConnectionStringException("parse error. token is null. Expected token=')");
}
// We can check by == because the token object is singleton.
if (!(token == TOKEN_KEY_END_OBJECT)) {
throw new OracleConnectionStringException("Syntax error. Expected token=')' :" + token.getToken());
}
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Complete each pair so it reads (KEY=value) with the '=' and value present and the block closed with ')'
- Re-copy the descriptor from the original source and diff against the failing URL
- Check config preprocessing (quoting, escaping, templating) isn't stripping the '=' and remainder
- Fail fast in config validation by pre-parsing the JDBC URL at startup
Example fix
// before String url = "jdbc:oracle:thin:@(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME"; // ends after key // after String url = "jdbc:oracle:thin:@(DESCRIPTION=(CONNECT_DATA=(SERVICE_NAME=svc)))";
Defensive patterns
Strategy: validation
Validate before calling
static boolean hasKeyValuePairs(String descriptor) {
// naive check: no block ends right after an identifier without '='
return !descriptor.matches(".*\\([A-Za-z_][A-Za-z0-9_]*$.*")
&& descriptor.endsWith(")");
} Try / catch
try {
parser.parse(url);
} catch (OracleConnectionStringException e) {
log.error("Oracle descriptor ended after a key, missing '=': {}", url, e);
throw new ConfigurationException("Incomplete KEY=value pair in descriptor", e);
} Prevention
- Ensure every '(' KEY is followed by =value before the closing ')'
- Check that config preprocessing isn't cutting values at '=' or whitespace
- Validate the full URL end-to-end (balance and pair check) before startup
When it happens
Trigger: A descriptor like '(CONNECT_DATA' or '(SERVICE_NAME' where the string ends after the key — the tokenizer is exhausted when checkEqualToken() asks for the '=' token.
Common situations: Truncated copy-paste of long descriptors; config parsing that cut the value at '=' or whitespace; template variables that expanded to nothing after the key name.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Syntax error. lookAheadToken is null
- description node not found
- description_list node not found
- invalid oracle jdbc url. expected token:(thin or oci) url:<u
- parsing error. expected token:'EOF' token:null
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/9ae8c8b60d833127.
Report an issue: GitHub.