Informix Error -103
-103 ISAM error: illegal key descriptor (too many parts or too long).
The ISAM processor has been given an invalid key descriptor. For C-ISAM programs, review the key descriptor. Each key descriptor has a maximum of 8 parts and 120 characters. If the error recurs, refer to the information on trapping errors in your Administrator's Guide or Reference to Appendix entitled "Trapping Errors" in your Administrator's Guide or Reference to acquire additional diagnostics. Contact IBM Informix Technical Support with the diagnostic information.
Oninit® Troubleshooting Guidance
Reasons / Common Causes
-103 is the specific, named case of -102 ("illegal argument to ISAM function") reached when the illegal argument is a key descriptor: the ISAM processor enforces two hard limits on any key — at most 8 parts, and at most 120 characters combined — and the descriptor presented broke one of them. Unlike most causes in this error family, this one is rarely a coding mistake in the sense of a wrong pointer or missed check; it's almost always a key definition that's simply too big for the layer that has to represent it.
Realistic causes:
- A composite index or key defined across more than 8 columns. The limit is on parts, not bytes, so this can happen even with short columns — a reporting or ETL tool that composes a "uniqueness" key across every business-identifying column in a wide table is the classic trigger.
- Aggregate key length crossing 120 characters after a column was widened, even with the
same number of parts.
ALTER TABLE ... MODIFYwidening aVARCHARorCHARcolumn that participates in a multi-column index is easy to do without anyone recalculating the combined key length that change now produces. - A dynamically-built key descriptor whose part count grows over time — a generic tool that composes a key across "all columns matching some rule" (all non-null columns, all columns flagged as part of a natural key, etc.) can cross the 8-part ceiling silently as the underlying table gains columns, with no code change of its own.
- Porting a schema or constraint from another engine that permits wider composite unique constraints — the source system's definition may be entirely valid there and simply unrepresentable as a single ISAM key here.
NCHAR/NVARCHARor other multi-byte-capable columns in a composite key, where the byte length the ISAM layer measures exceeds what a developer estimated from the character length alone.- A corrupted or incorrectly hand-constructed
keydescstructure — a pointer or indexing bug elsewhere in a program can produce akeydescthat reports an inflated part count or length without the intended key definition actually being that large. This is rarer than the size-related causes above but worth ruling out if the reported violation doesn't match a manual count of the intended key.
Solutions / Resolution
- Reduce the key to 8 or fewer parts. Reconsider whether every column actually needs to participate — a composite uniqueness check across many columns is often better expressed as a single computed/hash column with a unique index on that one derived value.
- Recalculate aggregate key length whenever a column that participates in a multi-column key is widened. Make this an explicit step in schema-change review for any column that appears in an index, not something discovered only when a build or load fails afterward.
- For a tool that builds keys dynamically, validate part count and total length at
construction time — before ever calling
isbuild()/isaddindex()— and fail with a message naming which columns to drop, rather than letting the ISAM layer's own -103 be the first feedback a user sees. - When a wide composite uniqueness constraint can't fit in 8 parts / 120 characters, use a computed hash or concatenation column (maintained by the application, a trigger, or a generated column depending on version) and put the unique index on that single derived column instead of the original wide combination.
- For
NCHAR/multi-byte columns, compute key length in bytes, not characters, when composing a key programmatically — that's what the ISAM layer itself measures, and the two can diverge significantly for multi-byte character sets. - If the reported violation doesn't match a manual count of the intended key, suspect
keydesccorruption rather than a genuinely oversized definition, and investigate the surrounding code for a pointer or indexing bug (see Diagnostic Checks).
Examples
Too many parts
-- Ten columns pressed into one composite "natural key" index
CREATE UNIQUE INDEX wide_key_idx ON shipment
(
origin, destination, carrier, mode, customer_ref,
order_ref, batch_id, leg_number, unit_id, revision
);
-- -103: 10 parts exceeds the 8-part limit
The fix is structural, not a syntax correction — this key needs to shrink, or become a single computed column, not be reformatted.
Length creeping past the limit after a widen
-- Original: combined key length comfortably under 120 characters
CREATE TABLE document (doc_ref VARCHAR(40), region VARCHAR(20), rev_tag VARCHAR(20));
CREATE UNIQUE INDEX doc_key_idx ON document (doc_ref, region, rev_tag); -- fine, 80 chars
-- Months later: doc_ref widened for a new integration that uses longer references
ALTER TABLE document MODIFY (doc_ref VARCHAR(90));
-- Same 3-part index, but now 130 characters combined
-- Next index rebuild or isbuild() call: -103
Nothing about the index definition changed — the column widening did, and nobody recalculated what that meant for the key it participates in.
Dynamic key-building tool crossing the ceiling
/* Generic "uniqueness enforcer": builds a key across every column
flagged as part of the business key, whatever that ends up being */
for (i = 0; i < business_key_column_count; i++) {
add_key_part(&kd, business_key_columns[i]);
}
isbuild(fname, RECORDLEN, &kd, ISINOUT);
/* business_key_column_count reached 9 after the last schema change — -103 */
The tool's logic is correct in isolation; the failure only appears once the table it's pointed at crosses a threshold the tool never validated against.
Diagnostic Checks
- Count the intended key's parts and sum its column lengths against the catalog directly:
SumSELECT c.colname, c.collength FROM sysindexes i JOIN systables t ON i.tabid = t.tabid JOIN syscolumns c ON c.tabid = t.tabid AND c.colno IN (i.part1, i.part2, i.part3, i.part4, i.part5, i.part6, i.part7, i.part8) WHERE t.tabname = 'shipment' AND i.idxname = 'wide_key_idx';collengthacross the returned rows and compare against 120; count the rows against 8. - For a dynamically-built key, log the part count and computed total length immediately
before the
isbuild()/isaddindex()call that fails. - For a recent widen as the suspected trigger, check
ALTER TABLEhistory (application change logs, or the table's own DDL history if tracked) for column-length changes touching any indexed column. - If the reported size doesn't match a manual count, suspect
keydesccorruption — review the construction code for pointer or loop-bound bugs, and consider running the build under a memory-checking tool if the discrepancy can't be explained by the key definition itself.
Related Errors / Related Topics
- -100 — "ISAM error: duplicate value for a record with unique key." The other foundational ISAM-level error in this family, reached through the same API surface.
- -102 — "ISAM error: illegal argument to ISAM function." The general form of this error — -103 exists as a separate, named code specifically because an oversized key descriptor is common and diagnosable enough (fixed 8-part/120-character limits) to call out on its own rather than leaving it folded into the generic -102.
If the part count or length you calculate by hand doesn't match what the error implies, don't assume the key definition itself is the problem — check for structure corruption first, per Diagnostic Checks above.