Your theory seems correct. Yes, Pollen is the only #lang returning #f for read-language, e.g.:
#lang racket/base
(map
(λ(lang) (read-language (open-input-string (format "#lang ~a" lang))))
'(racket racket/base scratchy scribble/manual scribble/text rackjure pollen))
'(#<procedure:language-info>
#<procedure:language-info>
#<procedure:...atchy/reader.rkt:26:2>
#<procedure:language-info>
#<procedure:language-info>
#<procedure:language-info>
#f)
Moreover, if I use your main.rkt, it triggers the same problem in DrRacket (#lang line is red, no toolbar buttons)
But beyond the issue of whether the docs or DrRacket is doing the right thing with the #f value, I'm unclear why Pollen is returning #f for read-language. One possibly unorthodox thing I'm doing here is that my #lang files rely on macro expansion. For instance, here's Pollen's main.rkt:
#lang racket/base
(require pollen/main-base)
(define+provide-module-begin-in-mode world:mode-preproc)
(module reader racket/base
(require pollen/reader-base)
(define+provide-reader-in-mode world:mode-auto))
... where `define+provide-module-begin-in-mode` is a macro that creates the #%module-begin macro, and `define+provide-reader-in-mode` is a macro that creates the reader.
This doesn't bother DrRacket when the file is being run, but perhaps this approach is incompatible with either read-language, or DrRacket's #lang validation?