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 normallyclient.boolVariation('beta-dashboard', { userId: 'u_1', plan: 'pro' }, false);
// Client SDK with no segment data: the rule cannot resolve, so no matchclient.boolVariation('beta-dashboard', { userId: 'u_1', plan: 'pro' }, false); // -> falseIf 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.
Related questions
Why did my targeting rule not match?
Rules run top to bottom and the first match wins, so an earlier rule can shadow the one you are testing. The other usual cause is a missing context attribute.
Why doesn't my semver targeting rule match?
Semver operators parse the version string before comparing. A build number, a date, or anything else that is not a version matches nothing at all.
Why is my feature flag returning the default value?
Six reasons a Featureflip flag falls back to the default you passed, ordered by how often each one is the real cause, with the check for each.
Still stuck?
The docs cover every SDK, and the free Solo plan is enough to reproduce most of these locally.