Diagnose in crossing order, from the writer to the flag. Each check is cheap and each has a known failure it finds.
Read the write-pointer logic: the value crossing into the read domain must change by exactly one bit per write step, which is the Gray property in The One-Bit-Change Rule. A binary counter, or a Gray counter with a non-power-of-two range handled naively, changes several bits at once under bursts, and the read domain samples torn values. This is the waived-warning trap: a Gray-code warning waived without transition proof is a confession, not a disposition.
Two flops minimum per bit, no logic between them, all in the read clock. Fewer stages, shared stages, or a "fast" single stage under burst rates each turn pointer latency into flag error. Reference: Gray Pointers in Signoff.
Empty must be generated in the read domain from the local read pointer and the synchronised write pointer, never by combining crossings from both directions in one comparison. A comparison that mixes a fresh write crossing with a fresh read crossing reconverges two skews and glitches exactly like this scenario. Reference: What Is Reconvergence.
If the write and read pointers release from reset on different cycles or in different values, the FIFO starts in a state that reads as empty, or as full, until the pointers lap into agreement. Under some reset sequences the symptom appears; under others it does not, which matches "only sometimes". Reference: FIFO Reset and Tool Checks.
Assumption: bursty writes move the pointer fastest when synchroniser latency matters most. Mechanism: the read-domain empty comparison samples a write pointer that is stale or torn, momentarily equals the read pointer, and asserts empty. Trade-off preview: each candidate fix costs differently, which the next lesson prices. Evidence: a pointer-transition assertion plus a structural report on the pointer crossing.
Reset alignment or comparison placement: burst-only transient errors with correct encoding and synchronisers point at stale-pointer latency seen by a misplaced comparison, or at pointers that started misaligned and only agree after lapping.