Informix Error -108
-108 ISAM error: key already exists.
The ISAM processor has been asked to create an index that already exists. For C-ISAM programs, review the program logic. The program must delete this existing index before it defines another. If the error recurs, note all circumstances and contact IBM Informix Technical Support.
Oninit® Troubleshooting Guidance
Reasons / Common Causes
-108 is easy to confuse with -100 because both mention "key" and "already exists," but they're different layers of the same idea. -100 is about data: a row's value collides with an existing row under a unique index. -108 is about definition: something asked the ISAM processor to create an index that, as a structure, already exists on the file. No row data is involved — the conflict is between two attempts to define the same key, not between two rows.
- Re-running an index-creation step that already succeeded once, without checking first —
the classic non-idempotent-migration pattern. A setup or migration script that unconditionally
issues
isaddindex()/CREATE INDEXwill hit -108 the second time it runs against a table that already has that index, whether the re-run was intentional (a retry after an unrelated failure partway through the script) or accidental (the script ran twice). - A partially-failed migration retried from the start rather than from the point of failure — if index creation was step 3 of 5 and step 4 failed, blindly re-running the whole script redoes step 3 and collides with what it already created.
- A concurrent race — two processes both attempting to create the same index at close to the same time; one succeeds, the other gets -108.
- Restoring a table from backup without accounting for indexes the restore already brings back, then running a separate post-restore step that unconditionally (re-)creates the same indexes.
- Application-side tooling that tracks its own idea of "has this index been created?" drifting out of sync with the actual database state — the tooling believes the index is missing and tries to create it, when the database catalog already has it.
- Schema-setup scripts written assuming a clean install, run instead against a table that was already provisioned (a staging environment reused for a fresh deploy test, for example).
Solutions / Resolution
- Check for existence before creating, rather than assuming a clean state — for SQL, query
the catalog first; for C-ISAM, track index state explicitly rather than assuming this is the
first time
isaddindex()has run against this file. - Make migration/setup scripts idempotent. Informix's
CREATE INDEXdoesn't carry a universalIF NOT EXISTSacross every version, so guard it explicitly:
or catch -108 in the migration runner and treat it as "already in the desired state" rather than a failure that aborts the run.-- Check first, create only if missing SELECT idxname FROM sysindexes WHERE idxname = 'cust_email_uq'; -- if no row returned, proceed with CREATE INDEX - For C-ISAM programs, follow the official guidance directly: delete the existing index with
isdelindex()before defining another, if re-creating it is genuinely the intent. - Serialize index-creation steps if concurrent invocations of the same setup/migration logic are possible — a single migration runner or an explicit lock prevents the race in Reasons #3.
- Reconcile application-tracked index state against the actual catalog if drift is the root cause — treat the database as the single source of truth rather than maintaining a parallel record of what's been created.
- For restore scenarios, decide explicitly whether the restore or a separate step owns index creation — don't let both paths unconditionally attempt it.
- If -108 recurs with none of the above explaining it, capture the full circumstances (what script, what table, what timing) and escalate to IBM Informix Technical Support per the official guidance — an unexplained recurrence may point at a catalog inconsistency below the application layer.
Examples
The non-idempotent migration
-- migration_007.sql — run once, succeeds
CREATE UNIQUE INDEX cust_email_uq ON customer (email);
-- Accidentally re-run months later (a migration runner without a
-- "have I already applied this?" check)
CREATE UNIQUE INDEX cust_email_uq ON customer (email);
-- -108: the index already exists
The fix isn't the SQL itself — it's the migration runner's lack of a guard against re-applying an already-applied step.
Retried from the start after a partial failure
Step 1: ALTER TABLE orders ADD COLUMN region VARCHAR(20); -- succeeds
Step 2: UPDATE orders SET region = 'unknown' WHERE region IS NULL; -- succeeds
Step 3: CREATE INDEX orders_region_idx ON orders (region); -- succeeds
Step 4: ALTER TABLE orders ADD CONSTRAINT ...; -- fails (unrelated issue)
-- Operator re-runs the whole script from Step 1 after fixing Step 4's issue
Step 1: fails now (column already exists) — or is skipped
Step 3: CREATE INDEX orders_region_idx ... -- -108: already created by the first run
Restarting from the beginning re-does work that already succeeded — the fix is either resuming from the actual failure point, or making every step idempotent.
C-ISAM: recreating deliberately
/* Intentionally redefining an index's structure */
isdelindex(fd, &old_keydesc); /* remove the existing definition first */
isaddindex(fd, &new_keydesc); /* now safe to add */
Skipping the isdelindex() call and going straight to isaddindex() with an unchanged or
overlapping key definition is what -108 reports.
Diagnostic Checks
- Check the catalog for the index before creating it:
SELECT idxname, idxtype FROM sysindexes i JOIN systables t ON i.tabid = t.tabid WHERE t.tabname = 'customer'; - Review migration/script run history — has this specific step run before against this database, even if an earlier or later step in the same run failed?
- Check for concurrent execution — was another process (a second deploy, a parallel CI job) plausibly running the same setup step at the same time?
- For C-ISAM programs, confirm whether
isdelindex()ran successfully before the failingisaddindex()call, if the intent was to redefine an existing index. - For restore-related cases, confirm whether the restore process itself already recreates indexes, before running a separate index-creation step against the restored table.
Related Errors / Related Topics
- -100 — "ISAM error: duplicate value for a record with unique key." Easy to conflate with -108 by name, but a different layer: -100 is a data-level collision between rows; -108 is a definition-level collision between two attempts to create the same index structure.
If you're debugging -108 and instinctively reach for the same fixes as -100 (finding a "duplicate row"), stop — there's no row involved here. The question is whether the index itself already exists, not whether any data collides.