[QGIS-Developer] Line feature callout labels not rendering in headless/server QGIS 3.22, but work fine in Desktop 3.28

吉見 崚 r-yoshimi at coel-inc.jp
Mon Aug 3 23:58:15 PDT 2026


Hi all,
My name is Yoshimi, a company employee based in Nagoya, Japan. I'm not a core GIS developer, but I've run into an issue during a project and would appreciate any pointers from this community.
I'm running into an issue where simple callout labels on LineString features fail to render at all when generated via a headless QGIS batch process (PyQGIS, Linux container), while the exact same .qml style and the exact same data render the callouts correctly when loaded manually in QGIS Desktop.
Environment:

  *   QGIS Desktop version (works correctly): 3.28.0, Windows
  *   QGIS server/headless version (fails): 3.22 (Ubuntu 22.04 apt package, qgis + python3-qgis), running in a Docker container, driven via PyQGIS (QgsApplication headless, no GUI event loop)
  *   Data source: PostGIS, LineString geometry, EPSG:6677
  *   Output: PDF via QgsLayoutExporter (print layout export)

Label/callout configuration (rule-based labeling):

<placement priority="5" placementFlags="10" placement="6" dist="30"
           overlapHandling="AllowOverlapIfRequired" .../>
<rendering unplacedVisibility="1" obstacle="0" .../>
<callout type="simple">
  ... anchorPoint="point_on_exterior" labelAnchorPoint="point_on_exterior"
      minLength="0" offsetFromAnchor="0" offsetFromLabel="0" ...
</callout>


Symptom:

  *   The line geometry itself renders correctly in the output PDF.
  *   The callout (leader line + label box) is completely absent in the batch/server output — not partially clipped, not overlapping with anything, just not drawn at all.
  *   No errors or warnings appear in the QGIS process log during style loading (layer.loadNamedStyle() returns success) or during layout export.
  *   Forcing unplacedVisibility="1" (always show, even if placement fails) made no difference.
  *   Changing anchorPoint from pole_of_inaccessibility to point_on_exterior made no difference.
  *   Ruled out: NULL/empty label field values (confirmed via logs), layer density/overlap competition (confirmed via an isolated manual test loading only the affected features), clipping at the map item's boundary edge.
  *   The same .qml, loaded onto the same features in QGIS Desktop 3.28.0, renders the callouts perfectly.

Question: Is there a known behavioral difference between QGIS 3.22 and 3.28 (or between interactive Desktop rendering and headless/server rendering via QgsLayoutExporter) regarding callout placement for line geometries? Or any known issue/limitation with calloutType="simple" specifically in non-interactive/headless rendering contexts?
Any pointers on where to look (label engine internals, GEOS version dependency, changelog entries between 3.22 and 3.28 related to labeling/callouts, missing processEvents() calls, etc.) would be greatly appreciated.
Thanks, Yoshimi



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20260804/88300d72/attachment-0001.htm>


More information about the QGIS-Developer mailing list