Quick answer: Call CommitAbility inside ActivateAbility to apply both cost and cooldown. Verify the Cooldown Gameplay Effect has Duration Policy set to Has Duration (not Instant or Infinite). Let the server own cooldown expiry — never manually remove the cooldown tag on the client.

You set up a fireball ability in GAS. It fires once, the cooldown starts, and then the ability stays on cooldown forever. Or it resets instantly and the player can fire every frame. Both bugs come from the same place: the Cooldown Gameplay Effect is not configured or applied correctly, and the fix is a few settings in the GE asset plus one missing function call in the ability.

How GAS Cooldowns Work

In the Gameplay Ability System, cooldowns are implemented as Gameplay Effects (GEs). When an ability activates, it applies a “Cooldown GE” to the owning Ability System Component (ASC). The GE grants a Gameplay Tag (e.g. Cooldown.Ability.Fireball) for a set duration. While the tag is active, the ability’s CanActivateAbility check fails because it queries GetCooldownTimeRemaining and sees the tag.

When the GE duration expires, the tag is removed, and the ability becomes available again. If any part of this chain is broken — wrong duration policy, missing CommitAbility call, manual tag manipulation — the cooldown either never starts or never ends.

The Symptom

The Fix

Step 1: Use CommitAbility.

Inside your ability’s ActivateAbility, call CommitAbility before doing any gameplay work. This function applies both the Cost GE (mana, stamina) and the Cooldown GE in one call, with the correct replication settings.

void UGA_Fireball::ActivateAbility(
    const FGameplayAbilitySpecHandle Handle,
    const FGameplayAbilityActorInfo* ActorInfo,
    const FGameplayAbilityActivationInfo ActivationInfo,
    const FGameplayEventData* TriggerEventData)
{
    if (!CommitAbility(Handle, ActorInfo, ActivationInfo))
    {
        EndAbility(Handle, ActorInfo, ActivationInfo, true, true);
        return;
    }

    // Cooldown GE is now active. Do gameplay work.
    SpawnFireball();
}

If you skip CommitAbility and apply the cooldown GE manually, you are responsible for getting the replication, duration, and tag grant correct. Most bugs come from this manual path.

Step 2: Verify the Cooldown GE asset.

Open the Gameplay Effect asset referenced by your ability’s GetCooldownGameplayEffect override. Check these fields:

If Duration Policy is Instant, the GE applies and removes in the same frame — the cooldown never appears. If it is Infinite, the GE never expires and the ability is locked out forever.

Step 3: Server authority.

Cooldown GEs should be applied on the server and replicated to the client. The client predicts the cooldown for UI responsiveness, but the server is the source of truth. If you manually remove the cooldown tag on the client (e.g. in a UI callback), the client thinks the ability is ready while the server still blocks it. The next activation attempt is rejected by the server and nothing happens.

Never call RemoveActiveGameplayEffect on a cooldown GE from the client. Let the duration expire naturally.

Debugging with the GAS Debugger

Press backtick and type showdebug abilitysystem to open the GAS debugger HUD. It shows:

If the cooldown tag is present but the duration says 0.0, the GE expired but the tag was not removed — a sign of a stacking or manual-removal bug. If the cooldown tag is absent but the ability reports “on cooldown,” your tag query in GetCooldownTags does not match the tag granted by the GE.

Common Edge Cases

Cooldown resets on respawn. If the player’s ASC is destroyed and recreated on death, all active GEs (including cooldowns) are lost. Either persist cooldown state across respawns or accept that death resets cooldowns (which is often the right design choice).

Cooldown applies but UI does not show it. The UI widget is querying the wrong tag or the wrong ASC. Verify the widget’s tag query matches the Cooldown GE’s Granted Tags exactly.

Multiple abilities sharing a cooldown. Use a shared cooldown tag (e.g. Cooldown.Category.Fire) on all fire abilities. Each ability’s Cooldown GE grants the same tag. Activating any one puts all of them on cooldown.

“GAS cooldowns are just Gameplay Effects with a tag and a timer. If the tag is wrong, the timer is wrong, or CommitAbility is missing, the cooldown breaks. Check all three before you look anywhere else.”

Related Issues

For abilities that do not activate at all, see Unreal Gameplay Ability not activating. For gameplay cues that do not play on the client, see Unreal Gameplay Cue not playing on client. For broader Blueprint event issues, see Unreal Blueprint event not firing.

Always use CommitAbility. It handles cost, cooldown, and replication in one call. Doing any of those manually is where 90% of GAS cooldown bugs come from.