Right now clickhouse allows to create TTL columns for Distributed tables during alters. It is working normally until server restart. After that it won't start because engine distributed doesn't support TTL clause. Modify metadata is required.

My cluster has 21.3 but tested it also with 21.11 and the same behavior.
It is blocked during create but it should be also be blocked during alters.
Tested on table from tutorial
ENGINE = Distributed('stage, 'default', 'hits_v1') 
alter table hits_v1_all modify column UTMCampaign String TTL EventDate + INTERVAL 1 MONTH ← it passes normally
explicit IStorage(StorageID storage_id_)
        : storage_id(std::move(storage_id_))
        , metadata(std::make_unique<StorageInMemoryMetadata>()) {} 
    IStorage(const IStorage &) = delete;
    IStorage & operator=(const IStorage &) = delete;
    
    virtual std::string getName() const = 0;
    
    StorageID getStorageID() const;
    
    virtual bool isRemote() const { return false; }
    
    virtual bool isView() const { return false; }
    
    virtual bool isDictionary() const { return false; }
    
    virtual bool supportsSampling() const { return getInMemoryMetadataPtr()->hasSamplingKey(); }
    
    virtual bool supportsFinal() const { return false; }
    
    virtual bool supportsPartitionBy() const { return false; }
    
    virtual bool supportsPrewhere() const { return false; }
    
    virtual bool canMoveConditionsToPrewhere() const { return supportsPrewhere(); }
    
    virtual bool supportsReplication() const { return false; }
    
    virtual bool supportsParallelInsert() const { return false; }