Why doesn't my segment match any users?

Last updated:

Usually because the rule cannot resolve the segment at all, which fails closed and matches nobody. A client SDK that was never given segment data behaves the same way. If the segment does resolve, the next suspect is condition logic: segments use one flat condition list with a single AND or OR, so a segment built to catch two different user groups with AND matches nobody by construction.

A segment that matches nobody and a segment that cannot be found look identical from the outside. Both serve the fallthrough. The difference matters because only one of them is a condition problem.

When a rule references a segment, the evaluator resolves that segment first. If it cannot, the rule fails closed and reports no match. It deliberately does not fall back to the rule’s own condition list, because an empty condition list matches everyone, and silently serving a feature to your entire user base is a far worse failure than serving it to nobody.

The resolution case

This is the one that surprises people, and it shows up most in browsers.

// Server SDK: segments arrive with the flag payload, rule resolves normally
client.boolVariation('beta-dashboard', { userId: 'u_1', plan: 'pro' }, false);
// Client SDK with no segment data: the rule cannot resolve, so no match
client.boolVariation('beta-dashboard', { userId: 'u_1', plan: 'pro' }, false); // -> false

If a flag works from your backend and not from the browser while both send the same attributes, check whether the segment is reaching the client at all before touching any conditions.

The condition case

If the segment does resolve, look at how it combines conditions. A segment carries one flat list plus a single operator for the whole list, unlike a targeting rule, which supports several condition groups combined with AND.

That difference bites in one specific way. A segment meant to capture “enterprise customers or anyone on the beta programme” written with AND requires both to be true of the same person, and typically nobody qualifies. Switch the operator to OR, or split it into two segments.

Attribute types are the other frequent culprit. A condition comparing plan to the string "pro" will not match a context sending a number, and a condition on signup_date needs the format the operator expects.

Checking it quickly

Evaluate one user you are certain belongs in the segment and read the reason back. A RuleMatch naming a different rule tells you something above it captured the user first, since rules run in priority order and the first match wins. A fallthrough reason tells you the segment rule genuinely did not match, which narrows it to the two causes above.

Segment structure is documented in How to use segments, and rule precedence in Targeting and segments.

Still stuck?

The docs cover every SDK, and the free Solo plan is enough to reproduce most of these locally.