Guide · Node.js · SDK · REST API

UUID Validation in Node.js — Versions, Variants, and Common Pitfalls

UUIDs power database primary keys, distributed system coordination, and API idempotency tokens — but not all 128-bit identifiers are created equal. Here's how to validate them properly, detect the version and variant, and avoid the traps that regex alone cannot catch.

1. Why UUID validation matters

A Universally Unique Identifier (UUID) is a 128-bit label used to identify resources across systems without coordination. UUIDs appear as database primary keys (PostgreSQL's uuid type), distributed system node identifiers, message deduplication keys, and API idempotency tokens.

Accepting an invalid UUID can corrupt your data layer, cause silent lookup failures, or break downstream services that expect a specific version. In event-driven architectures, a malformed idempotency key can lead to duplicate processing or lost events.

ℹ️UUIDs are defined by RFC 9562 (formerly RFC 4122). The specification covers versions 1 through 8, plus the nil and max UUIDs. Each version has different generation rules and uniqueness guarantees.

2. UUID versions explained

Not all UUIDs are random. Each version encodes different information and is suited for different use cases:

VersionNameHow it works
v1Timestamp + MACCombines a 60-bit timestamp with the node's MAC address. Sortable by time but leaks hardware identity.
v3MD5 namespaceDeterministic hash of a namespace UUID + name using MD5. Same input always produces the same UUID.
v4RandomGenerated from 122 random bits. Most widely used — simple and collision-resistant.
v5SHA-1 namespaceLike v3 but uses SHA-1 instead of MD5. Preferred for new namespace-based IDs.
v6Reordered timeLike v1 but with the timestamp bits reordered for natural sortability. Draft in RFC 9562.
v7Unix timestamp + randomCombines a 48-bit Unix millisecond timestamp with random bits. Sortable and privacy-friendly.
If you're choosing a UUID version for a new project: use v4 when you need simple random IDs, or v7 when you need sortable, time-ordered keys (great for database indexes).

3. The anatomy of a UUID

A UUID is displayed as 32 hexadecimal digits in the canonical 8-4-4-4-12 format, separated by hyphens:

550e8400-e29b-41d4-a716-446655440000
Version nibble (4 = v4)Variant bits (a = RFC 4122)

Version nibble

The 13th hex digit (first nibble of the third group) encodes the UUID version. For a v4 UUID it is always 4, for v7 it is 7, and so on. The version ranges from 0 to 15.

Variant bits

The 17th hex digit (first nibble of the fourth group) encodes the variant. For the standard RFC 4122 variant, this nibble is 8, 9, a, or b. Other values indicate NCS backward compatibility, Microsoft GUIDs, or reserved-for-future variants.


4. Why regex isn't enough

The most common approach to UUID validation in Node.js is a regex like this:

// ❌ Matches the format but ignores version and variant
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

This regex checks the shape of a UUID but misses critical semantic checks:

Valid format, wrong version

The string 550e8400-e29b-f1d4-a716-446655440000 matches the regex but has version nibble f (15), which is not a standard UUID version. If your system requires v4 UUIDs, the regex will happily accept this invalid input.

No variant checking

Microsoft GUIDs use a different variant encoding than RFC 4122 UUIDs. A regex cannot distinguish between the two. If your database column expects RFC 4122 UUIDs, accepting a Microsoft-variant GUID can cause interoperability issues.

Version-specific enforcement

If your API contract specifies "v4 UUID only" (e.g. for idempotency keys), you need to verify both the format and the version nibble. A regex that tries to encode all version rules becomes unmaintainable.

⚠️A string can match the UUID format perfectly and still be semantically invalid. Proper validation requires checking the version nibble, variant bits, and optionally enforcing a specific version.

5. The right solution — IsValid API

The IsValid UUID API validates the format, detects the version (0-15) and variant (RFC 4122, NCS, Microsoft, or future), and optionally enforces a specific version — all in a single call.

Pass any string to the API and get back whether it is a valid UUID, which version it is, and which variant it uses. You can also filter by a specific version to reject UUIDs that don't match your requirements.

0–15
Versions
all RFC 9562 versions
<10ms
Response time
lightweight parsing
100/day
Free tier
no credit card

Full parameter reference and response schema: UUID API docs →


6. Node.js code example

Using the @isvalid-dev/sdk package or the native fetch API (Node 18+).

// validateUuid.js
import { createClient } from '@isvalid-dev/sdk';

const iv = createClient({ apiKey: process.env.ISVALID_API_KEY });

// ── Basic validation ─────────────────────────────────────────────────────────

const result = await iv.uuid('550e8400-e29b-41d4-a716-446655440000');

console.log(result.valid);   // true
console.log(result.version); // 4
console.log(result.variant); // 'rfc4122'

// ── Enforce a specific version ───────────────────────────────────────────────

const v7 = await iv.uuid('01932c07-209c-7f43-b572-6a8270527ca5', { version: 7 });

if (!v7.valid) {
  console.log('Not a valid v7 UUID');
}

In an Express middleware, validate incoming UUIDs before they reach your database:

// middleware/validateIdParam.js
export async function validateIdParam(req, res, next) {
  const { id } = req.params;
  if (!id) return next();

  try {
    const result = await iv.uuid(id, { version: 4 });
    if (!result.valid) {
      return res.status(400).json({
        error: 'Invalid resource ID',
        message: 'Expected a valid v4 UUID',
      });
    }
  } catch {
    // API unavailable — fall through to let the DB handle it
  }

  next();
}
Use the version option to enforce that incoming IDs match the UUID version your system generates. This catches copy-paste errors and malicious inputs early — before they hit your database.

7. cURL example

Validate a UUID from the command line:

curl -G -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "value=550e8400-e29b-41d4-a716-446655440000" \
  "https://api.isvalid.dev/v0/uuid"

Enforce a specific version (returns valid: false if the UUID is not v7):

curl -G -H "Authorization: Bearer YOUR_API_KEY" \
  --data-urlencode "value=550e8400-e29b-41d4-a716-446655440000" \
  --data-urlencode "version=7" \
  "https://api.isvalid.dev/v0/uuid"

8. Understanding the response

Valid v4 UUID:

{
  "valid": true,
  "version": 4,
  "variant": "rfc4122"
}

Invalid UUID (wrong format):

{
  "valid": false,
  "version": null,
  "variant": null
}
FieldTypeDescription
validbooleanWhether the input is a structurally valid UUID (and matches the requested version, if specified)
versionnumberDetected UUID version (0-15), extracted from the version nibble
variantstringVariant: rfc4122, ncs, microsoft, or future

9. Edge cases

Nil UUID

The nil UUID 00000000-0000-0000-0000-000000000000 is a valid UUID with version 0 and variant ncs. It is sometimes used as a placeholder or default value. The API will return valid: true with version: 0.

const nil = await iv.uuid('00000000-0000-0000-0000-000000000000');
// { valid: true, version: 0, variant: 'ncs' }

Max UUID

The max UUID ffffffff-ffff-ffff-ffff-ffffffffffff (RFC 9562) has all bits set to 1. It is valid and has version 15 with variant future. It is used as an upper bound sentinel in range queries.

Case sensitivity

RFC 9562 states that UUIDs should be output as lowercase but accepted case-insensitively. The API accepts both 550E8400-E29B-41D4-A716-446655440000 and its lowercase equivalent as valid.

Braces and URN format

Some systems wrap UUIDs in braces ({550e8400-...}) or use URN notation (urn:uuid:550e8400-...). Strip these wrappers before passing the value to the API — it expects the bare 32-hex-digit format with hyphens.


10. Summary

Don't rely on regex alone — it misses version and variant checks
Don't accept any UUID version when your system requires a specific one
Don't ignore the variant — Microsoft GUIDs differ from RFC 4122 UUIDs
Validate both format and semantics (version + variant) on every input
Use the version filter to enforce v4-only or v7-only policies
Handle nil and max UUIDs explicitly in your application logic
Strip braces and URN prefixes before validation

See also

Validate UUIDs instantly

Free tier includes 100 API calls per day. No credit card required. Detects all UUID versions and variants defined by RFC 9562.