NationalSecurityAgency/ghidra · error · IllegalArgumentException

No variant codec with selector {}

Error message

No variant codec with selector {}

What it means

Thrown (unchecked IllegalArgumentException) by PrimitiveCodec.getCodec(byte sel) when reading a variant field whose stored 1-byte type selector does not map to any known codec in CODECS_BY_SELECTOR. Each variant value is prefixed by a selector byte identifying its codec; an unknown selector means the data was written by a newer/different code version, the registry changed, or the bytes are corrupt.

Source

Thrown at Ghidra/Debug/ProposedUtils/src/main/java/ghidra/util/database/DBCachedObjectStoreFactory.java:1031

			@SuppressWarnings("unchecked")
			PrimitiveCodec<T> obj = (PrimitiveCodec<T>) CODECS_BY_CLASS.get(cls);
			if (obj == null) {
				throw new IllegalArgumentException("No variant codec for class " + cls);
			}
			return obj;
		}

		/**
		 * Get the codec for the given selector
		 * 
		 * @param sel the selector
		 * @return the codec
		 * @throws IllegalArgumentException if the selector is unknown
		 */
		static PrimitiveCodec<?> getCodec(byte sel) {
			PrimitiveCodec<?> obj = CODECS_BY_SELECTOR.get(sel);
			if (obj == null) {
				throw new IllegalArgumentException("No variant codec with selector " + sel);
			}
			return obj;
		}
	}

	/**
	 * A custom codec for field of "variant" type
	 * 
	 * <p>
	 * This is suitable for use on fields of type {@link Object}; however, only certain types can
	 * actually be encoded. The encoding uses a 1-byte type selector followed by the byte-array
	 * encoded value.
	 */
	public static class VariantDBFieldCodec<OT extends DBAnnotatedObject>
			extends AbstractDBFieldCodec<Object, OT, BinaryField> {
		public VariantDBFieldCodec(Class<OT> objectType, Field field, int column) {
			super(Object.class, objectType, BinaryField.class, field, column);
		}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Upgrade the reading code to a version whose codec registry includes the stored selector (align writer and reader versions).
  2. If the registry was intentionally changed, re-encode/migrate the affected records so their selectors are current.
  3. For corruption, restore from backup or rebuild the affected store from source data.
  4. Add a defensive check: log the unknown selector and skip/quarantine the record rather than aborting the whole read.

Example fix

// before: reading a newer-format variant field throws
Object v = store.getVariantField(rec); // "No variant codec with selector 17"

// after: tolerate unknown selectors from version skew
byte sel = rec.readSelector();
if (!PrimitiveCodec.hasCodec(sel)) {
    log.warn("unknown variant selector {}; skipping record", sel);
    continue;
}
Object v = PrimitiveCodec.getCodec(sel).decode(rec);
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the selector is known before decoding
if (!PrimitiveCodec.CODECS_BY_SELECTOR.containsKey(sel)) {
    // version skew or corruption: upgrade reader, migrate data, or skip record
}

Try / catch

try {
    Object v = PrimitiveCodec.getCodec(sel).decode(buf);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("No variant codec with selector")) { /* log + skip/quarantine */ }
    else throw e;
}

Prevention

When it happens

Trigger: Reading variant-field data that was encoded with a selector byte this code version doesn't recognise — typically a forward-compatibility/version-skew (data written by newer code with an added codec type) or byte-level corruption of the stored record.

Common situations: Opening a database created by a newer Ghidra/version that added a variant codec; a registry edit that removed or renumbered a selector; storage corruption producing a garbage selector byte; partial/aborted writes leaving a bad header.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/755771437f42d424. Report an issue: GitHub.