An unlogged table has an initialization fork. The initialization fork does not have an BM_PERMANENT flag when get a buffer. In checkpoint (not shutdown or end of recovery), it will not write to disk. after a crash recovery, the page of initialization fork will not correctly, then make the main fork not correctly too.
Here is an example for GIN index. create unlogged table gin_test_tbl(i int4[]); create index gin_test_idx on gin_test_tbl using gin (i); checkpoint; kill all the postgres process, and restart again. vacuum gin_test_tbl; -- crash. It seems have same problem in BRIN, GIN, GiST and HASH index which using buffer for meta page initialize in ambuildempty function.