neo4j/neo4j · error · IllegalArgumentException
Invalid tag. Tag must be in the format '<key>:<value>'! Prov
Error message
Invalid tag. Tag must be in the format '<key>:<value>'! Provided: '%s'
What it means
StorageTag.parse throws IllegalArgumentException when input.split(":") does not yield exactly two parts. The tag format is strictly '<key>:<value>' — one colon. Inputs with no colon ('keyvalue') or multiple colons ('k:v:extra', which splits into 3 parts) are rejected.
Source
Thrown at community/cloud/src/main/java/org/neo4j/cloud/storage/StorageTag.java:40
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
public record StorageTag(String key, String value) {
public static final String STORAGE_TAGS = "storage_tags";
public static StorageTag parse(String input) {
if (input == null || input.isEmpty()) {
throw new IllegalArgumentException("Invalid tag. Tag must not be empty or null!");
}
try {
var inputSplit = input.split(":");
if (inputSplit.length != 2) {
throw new IllegalArgumentException(
String.format("Invalid tag. Tag must be in the format '<key>:<value>'! Provided: '%s'", input));
}
return new StorageTag(inputSplit[0], inputSplit[1]);
} catch (PatternSyntaxException e) {
throw new IllegalArgumentException(
String.format("Invalid tag. Tag must be in the format '<key>:<value>'! Provided: '%s'", input));
}
}
public static void setTags(Path path, Collection<StorageTag> tags) {
if (!tags.isEmpty()) {
if (path instanceof StoragePath storagePath) {
storagePath.addMetadata(STORAGE_TAGS, tags);
} else {
throw new IllegalArgumentException("Cannot set tags on path which doesn't point to Object Storage");
}
}
}View on GitHub (pinned to f213380f81)
Solutions
- Rewrite the tag as exactly one colon: '<key>:<value>'
- If the value contains colons, encode or escape it, or split on first occurrence manually rather than via StorageTag.parse
- Validate with a regex like ^[^:]+:[^:]*$ before parsing and reject with a helpful message
Example fix
// before
StorageTag t = StorageTag.parse("endpoint:https://neo4j.example.com");
// after
int idx = input.indexOf(':');
StorageTag t = (idx > 0)
? new StorageTag(input.substring(0, idx), input.substring(idx + 1))
: StorageTag.parse(input); // let parse() reject truly malformed input Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern TAG = Pattern.compile("^([^:]+):([^:]*)$");
boolean ok = TAG.matcher(input).matches(); Type guard
static boolean isValidTagFormat(String s) { return s != null && s.split(":", -1).length == 2 && !s.split(":", -1)[0].isEmpty(); } Try / catch
try { return StorageTag.parse(input); } catch (IllegalArgumentException e) { throw new ConfigurationException("Bad storage tag '" + input + "', expected <key>:<value>", e); } Prevention
- For values containing colons, split on the first colon yourself and construct the record
- Document the single-colon rule wherever tag settings are exposed
When it happens
Trigger: StorageTag.parse("tag") (no colon); StorageTag.parse("a:b:c") (two colons → length 3); values containing colons such as URIs or timestamps ('key:https://x') which also split into more than 2 parts.
Common situations: Tag values that legitimately contain colons (URLs, key=value query strings, clock times); users writing 'key=value' instead of 'key:value'; copy-paste of ARNs or endpoints as tag values.
Related errors
- Invalid tag. Tag must not be empty or null!
- Cannot set tags on path which doesn't point to Object Storag
- Unsupported OpenOption(s):
- Illegal spec for writeable tier: expected 'batchesPerTier:ba
- nested list types is not supported.
AI-assisted analysis of neo4j/neo4j@f213380f81 (2026-08-14).
Data as JSON: /api/errors/0b91edef8b841bc4.
Report an issue: GitHub.