I finally got an answer from the American Galvanizers Association.
Due to inadequate combustion exhaust venting, combustion gases cool before they reach the exterior. This is usually caused by an excessively long- or too many bends in the- combustion vent. Cooling combustion gases condense on the inside of the galvanized steel vent where the condensation reacts with the galvanized steel, and the result is corrosion. The first, kinda liquidy, gooey product of this corrosion is zinc hydroxide, which slides down the inside of the vent onto the heating appliance (furnace, boiler, or water heater) where the rest of the moisture evaporates, leaving a white, powdery residue that is zinc oxide. Sometimes it doesn’t make it as far as the heating appliance and you can see it leaking from joints in the vent above the heating appliance.
Now, sometimes this condensation takes place where the vent protrudes above the roof. This makes sense because the vent will be colder above the roof, especially in cold climates, and a colder vent will cause more condensation to develop. Because this takes place way up high, the zinc hydroxide that forms up there will have a long way to travel before it falls out the bottom of the vent connector, and before it reaches the bottom, it may become trapped at bends in the vent. At any rate, some of the gooey zinc hydroxide will dry to powdery zinc oxide while it’s still inside the vent, and some of this powder will be caught up in the slipstream of the draft from the heating appliance and will be carried up, discharged out the vent, and deposited on the roof, and this is why you see white residue on the roof below combustion vents.
On older combustion appliances with vents made of steel that is not galvanized, this residue may be brown because the corrosion product of steel is iron oxide, not zinc oxide.