diff --git a/cluster-autoscaler/cloudprovider/aws/aws_cloud_provider.go b/cluster-autoscaler/cloudprovider/aws/aws_cloud_provider.go
index f9dc9a0ed1ed616312c0ad0b97449c3f6de0c0e5..9fa180e0c6b2dc3c1c6447c7b91b5476f64292d0 100644
--- a/cluster-autoscaler/cloudprovider/aws/aws_cloud_provider.go
+++ b/cluster-autoscaler/cloudprovider/aws/aws_cloud_provider.go
@@ -116,7 +116,12 @@ func (aws *awsCloudProvider) Refresh() error {
 	return aws.awsManager.Refresh()
 }
 
-// AwsRef contains a reference to some entity in AWS/GKE world.
+// GetInstanceID gets the instance ID for the specified node.
+func (aws *awsCloudProvider) GetInstanceID(node *apiv1.Node) string {
+	return node.Spec.ProviderID
+}
+
+// AwsRef contains a reference to some entity in AWS world.
 type AwsRef struct {
 	Name string
 }
diff --git a/cluster-autoscaler/cloudprovider/azure/azure_agent_pool.go b/cluster-autoscaler/cloudprovider/azure/azure_agent_pool.go
index bbc90c0af789088aa131938dab8e10c73873bfd4..d5e365c3229afbc593d2e208a9f614dfab7f869e 100644
--- a/cluster-autoscaler/cloudprovider/azure/azure_agent_pool.go
+++ b/cluster-autoscaler/cloudprovider/azure/azure_agent_pool.go
@@ -20,6 +20,7 @@ import (
 	"fmt"
 	"math/rand"
 	"sort"
+	"strings"
 	"sync"
 	"time"
 
@@ -129,7 +130,7 @@ func (as *AgentPool) GetVMIndexes() ([]int, map[int]string, error) {
 		}
 
 		indexes = append(indexes, index)
-		indexToVM[index] = "azure://" + *instance.ID
+		indexToVM[index] = "azure://" + strings.ToLower(*instance.ID)
 	}
 
 	sortedIndexes := sort.IntSlice(indexes)
@@ -234,7 +235,7 @@ func (as *AgentPool) GetVirtualMachines() (instances []compute.VirtualMachine, e
 
 		tags := *instance.Tags
 		vmPoolName := tags["poolName"]
-		if *vmPoolName != as.Id() {
+		if vmPoolName == nil || !strings.EqualFold(*vmPoolName, as.Id()) {
 			continue
 		}
 
@@ -284,7 +285,7 @@ func (as *AgentPool) Belongs(node *apiv1.Node) (bool, error) {
 	if targetAsg == nil {
 		return false, fmt.Errorf("%s doesn't belong to a known agent pool", node.Name)
 	}
-	if targetAsg.Id() != as.Id() {
+	if !strings.EqualFold(targetAsg.Id(), as.Id()) {
 		return false, nil
 	}
 	return true, nil
@@ -307,7 +308,7 @@ func (as *AgentPool) DeleteInstances(instances []*azureRef) error {
 			return err
 		}
 
-		if asg != commonAsg {
+		if !strings.EqualFold(asg.Id(), commonAsg.Id()) {
 			return fmt.Errorf("cannot delete instance (%s) which don't belong to the same node pool (%q)", instance.GetKey(), commonAsg)
 		}
 	}
@@ -390,7 +391,7 @@ func (as *AgentPool) Nodes() ([]string, error) {
 		}
 
 		// To keep consistent with providerID from kubernetes cloud provider, do not convert ID to lower case.
-		name := "azure://" + *instance.ID
+		name := "azure://" + strings.ToLower(*instance.ID)
 		nodes = append(nodes, name)
 	}
 
diff --git a/cluster-autoscaler/cloudprovider/azure/azure_cache.go b/cluster-autoscaler/cloudprovider/azure/azure_cache.go
index 6e8fabb8f26f58cf93f138561e4fabe2886b21ed..cc9dc3c5c7cbf31fdfa813640545443b2757a0fa 100644
--- a/cluster-autoscaler/cloudprovider/azure/azure_cache.go
+++ b/cluster-autoscaler/cloudprovider/azure/azure_cache.go
@@ -20,6 +20,7 @@ import (
 	"fmt"
 	"reflect"
 	"regexp"
+	"strings"
 	"sync"
 	"time"
 
@@ -28,7 +29,7 @@ import (
 	"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
 )
 
-var virtualMachineRE = regexp.MustCompile(`^azure://(?:.*)/providers/Microsoft.Compute/virtualMachines/(.+)$`)
+var virtualMachineRE = regexp.MustCompile(`^azure://(?:.*)/providers/microsoft.compute/virtualmachines/(.+)$`)
 
 type asgCache struct {
 	registeredAsgs     []cloudprovider.NodeGroup
@@ -63,7 +64,7 @@ func (m *asgCache) Register(asg cloudprovider.NodeGroup) bool {
 	defer m.mutex.Unlock()
 
 	for i := range m.registeredAsgs {
-		if existing := m.registeredAsgs[i]; existing.Id() == asg.Id() {
+		if existing := m.registeredAsgs[i]; strings.EqualFold(existing.Id(), asg.Id()) {
 			if reflect.DeepEqual(existing, asg) {
 				return false
 			}
@@ -94,7 +95,7 @@ func (m *asgCache) Unregister(asg cloudprovider.NodeGroup) bool {
 	updated := make([]cloudprovider.NodeGroup, 0, len(m.registeredAsgs))
 	changed := false
 	for _, existing := range m.registeredAsgs {
-		if existing.Id() == asg.Id() {
+		if strings.EqualFold(existing.Id(), asg.Id()) {
 			glog.V(1).Infof("Unregistered ASG %s", asg.Id())
 			changed = true
 			continue
@@ -117,7 +118,8 @@ func (m *asgCache) FindForInstance(instance *azureRef, vmType string) (cloudprov
 	m.mutex.Lock()
 	defer m.mutex.Unlock()
 
-	if m.notInRegisteredAsg[*instance] {
+	inst := azureRef{Name: strings.ToLower(instance.Name)}
+	if m.notInRegisteredAsg[inst] {
 		// We already know we don't own this instance. Return early and avoid
 		// additional calls.
 		return nil, nil
@@ -125,34 +127,37 @@ func (m *asgCache) FindForInstance(instance *azureRef, vmType string) (cloudprov
 
 	if vmType == vmTypeVMSS {
 		// Omit virtual machines not managed by vmss.
-		if ok := virtualMachineRE.Match([]byte(instance.Name)); ok {
+		if ok := virtualMachineRE.Match([]byte(inst.Name)); ok {
 			glog.V(3).Infof("Instance %q is not managed by vmss, omit it in autoscaler", instance.Name)
-			m.notInRegisteredAsg[*instance] = true
+			m.notInRegisteredAsg[inst] = true
 			return nil, nil
 		}
 	}
 
 	if vmType == vmTypeStandard {
 		// Omit virtual machines with providerID not in Azure resource ID format.
-		if ok := virtualMachineRE.Match([]byte(instance.Name)); !ok {
+		if ok := virtualMachineRE.Match([]byte(inst.Name)); !ok {
 			glog.V(3).Infof("Instance %q is not in Azure resource ID format, omit it in autoscaler", instance.Name)
-			m.notInRegisteredAsg[*instance] = true
+			m.notInRegisteredAsg[inst] = true
 			return nil, nil
 		}
 	}
 
-	if asg, found := m.instanceToAsg[*instance]; found {
+	// Look up caches for the instance.
+	if asg := m.getInstanceFromCache(inst.Name); asg != nil {
 		return asg, nil
 	}
 
+	// Not found, regenerate the cache and try again.
 	if err := m.regenerate(); err != nil {
-		return nil, fmt.Errorf("Error while looking for ASG for instance %+v, error: %v", *instance, err)
+		return nil, fmt.Errorf("error while looking for ASG for instance %q, error: %v", instance.Name, err)
 	}
-	if config, found := m.instanceToAsg[*instance]; found {
-		return config, nil
+	if asg := m.getInstanceFromCache(inst.Name); asg != nil {
+		return asg, nil
 	}
 
-	m.notInRegisteredAsg[*instance] = true
+	// Add the instance to notInRegisteredAsg since it's unknown from Azure.
+	m.notInRegisteredAsg[inst] = true
 	return nil, nil
 }
 
@@ -179,3 +184,15 @@ func (m *asgCache) regenerate() error {
 	m.instanceToAsg = newCache
 	return nil
 }
+
+// Get node group from cache. nil would be return if not found.
+// Should be call with lock protected.
+func (m *asgCache) getInstanceFromCache(providerID string) cloudprovider.NodeGroup {
+	for instanceID, asg := range m.instanceToAsg {
+		if strings.EqualFold(instanceID.GetKey(), providerID) {
+			return asg
+		}
+	}
+
+	return nil
+}
diff --git a/cluster-autoscaler/cloudprovider/azure/azure_cloud_provider.go b/cluster-autoscaler/cloudprovider/azure/azure_cloud_provider.go
index 3adfd9ea301f79165c623039cc5b5f85084b1052..08d50d8b1e281dcde91e7c414d42ab29edb6f445 100644
--- a/cluster-autoscaler/cloudprovider/azure/azure_cloud_provider.go
+++ b/cluster-autoscaler/cloudprovider/azure/azure_cloud_provider.go
@@ -17,6 +17,8 @@ limitations under the License.
 package azure
 
 import (
+	"strings"
+
 	"github.com/golang/glog"
 
 	apiv1 "k8s.io/api/core/v1"
@@ -105,6 +107,11 @@ func (azure *AzureCloudProvider) Refresh() error {
 	return azure.azureManager.Refresh()
 }
 
+// GetInstanceID gets the instance ID for the specified node.
+func (azure *AzureCloudProvider) GetInstanceID(node *apiv1.Node) string {
+	return strings.ToLower(node.Spec.ProviderID)
+}
+
 // azureRef contains a reference to some entity in Azure world.
 type azureRef struct {
 	Name string
diff --git a/cluster-autoscaler/cloudprovider/azure/azure_container_service_pool.go b/cluster-autoscaler/cloudprovider/azure/azure_container_service_pool.go
index 3aaf428e453cdf79550bb101a4e060d826ccf470..4bc122ea1be22575b4a497d34aee9e8080fd0301 100644
--- a/cluster-autoscaler/cloudprovider/azure/azure_container_service_pool.go
+++ b/cluster-autoscaler/cloudprovider/azure/azure_container_service_pool.go
@@ -78,7 +78,7 @@ func (agentPool *ContainerServiceAgentPool) GetAKSAgentPool(agentProfiles *[]con
 	for _, value := range *agentProfiles {
 		profileName := *value.Name
 		glog.V(5).Infof("AKS AgentPool profile name: %s", profileName)
-		if profileName == (agentPool.azureRef.Name) {
+		if strings.EqualFold(profileName, agentPool.azureRef.Name) {
 			return &value
 		}
 	}
@@ -92,7 +92,7 @@ func (agentPool *ContainerServiceAgentPool) GetACSAgentPool(agentProfiles *[]con
 	for _, value := range *agentProfiles {
 		profileName := *value.Name
 		glog.V(5).Infof("ACS AgentPool profile name: %s", profileName)
-		if profileName == (agentPool.azureRef.Name) {
+		if strings.EqualFold(profileName, agentPool.azureRef.Name) {
 			return &value
 		}
 	}
@@ -105,7 +105,7 @@ func (agentPool *ContainerServiceAgentPool) GetACSAgentPool(agentProfiles *[]con
 		profileName := *value.Name
 		poolName := agentPool.azureRef.Name + "pool0"
 		glog.V(5).Infof("Workaround match check - ACS AgentPool Profile: %s <=> Poolname: %s", profileName, poolName)
-		if profileName == poolName {
+		if strings.EqualFold(profileName, poolName) {
 			return &value
 		}
 	}
@@ -252,7 +252,7 @@ func (agentPool *ContainerServiceAgentPool) SetNodeCount(count int) (err error)
 func (agentPool *ContainerServiceAgentPool) GetProviderID(name string) string {
 	//TODO: come with a generic way to make it work with provider id formats
 	// in different version of k8s.
-	return "azure://" + name
+	return "azure://" + strings.ToLower(name)
 }
 
 //GetName extracts the name of the node (a format which underlying cloud service understands)
@@ -267,7 +267,7 @@ func (agentPool *ContainerServiceAgentPool) GetName(providerID string) (string,
 		return "", err
 	}
 	for _, vm := range vms {
-		if strings.Compare(*vm.ID, providerID) == 0 {
+		if strings.EqualFold(*vm.ID, providerID) {
 			return *vm.Name, nil
 		}
 	}
@@ -385,7 +385,7 @@ func (agentPool *ContainerServiceAgentPool) IsContainerServiceNode(tags *map[str
 	poolName := (*tags)["poolName"]
 	if poolName != nil {
 		glog.V(5).Infof("Matching agentPool name: %s with tag name: %s", agentPool.azureRef.Name, *poolName)
-		if *poolName == agentPool.azureRef.Name {
+		if strings.EqualFold(*poolName, agentPool.azureRef.Name) {
 			return true
 		}
 	}
diff --git a/cluster-autoscaler/cloudprovider/azure/azure_fakes.go b/cluster-autoscaler/cloudprovider/azure/azure_fakes.go
index ac09c49657b8b97081360f2aa9cc9f1cf95c82ae..38fba8073e8a803110d35bc8caef66837f909828 100644
--- a/cluster-autoscaler/cloudprovider/azure/azure_fakes.go
+++ b/cluster-autoscaler/cloudprovider/azure/azure_fakes.go
@@ -31,7 +31,7 @@ import (
 )
 
 const (
-	fakeVirtualMachineScaleSetVMID = "/subscriptions/test-subscription-id/resourceGroups/test-asg/providers/Microsoft.Compute/virtualMachineScaleSets/agents/virtualMachines/0"
+	fakeVirtualMachineScaleSetVMID = "/subscriptions/test-subscription-id/resourcegroups/test-asg/providers/microsoft.compute/virtualmachinescalesets/agents/virtualmachines/0"
 )
 
 // VirtualMachineScaleSetsClientMock mocks for VirtualMachineScaleSetsClient.
diff --git a/cluster-autoscaler/cloudprovider/azure/azure_scale_set.go b/cluster-autoscaler/cloudprovider/azure/azure_scale_set.go
index 9c35b59a59d5f62f0f13d575e49fb4249d7eaf58..24bdf12b8702ddb5f96ca26ae63b845dcf9a2b04 100644
--- a/cluster-autoscaler/cloudprovider/azure/azure_scale_set.go
+++ b/cluster-autoscaler/cloudprovider/azure/azure_scale_set.go
@@ -19,6 +19,7 @@ package azure
 import (
 	"fmt"
 	"math/rand"
+	"strings"
 	"sync"
 	"time"
 
@@ -46,8 +47,6 @@ type ScaleSet struct {
 	mutex       sync.Mutex
 	lastRefresh time.Time
 	curSize     int64
-	// virtualMachines holds a list of vmss instances (instanceID -> resourceID).
-	virtualMachines map[string]string
 }
 
 // NewScaleSet creates a new NewScaleSet.
@@ -56,11 +55,10 @@ func NewScaleSet(spec *dynamic.NodeGroupSpec, az *AzureManager) (*ScaleSet, erro
 		azureRef: azureRef{
 			Name: spec.Name,
 		},
-		minSize:         spec.MinSize,
-		maxSize:         spec.MaxSize,
-		manager:         az,
-		curSize:         -1,
-		virtualMachines: make(map[string]string),
+		minSize: spec.MinSize,
+		maxSize: spec.MaxSize,
+		manager: az,
+		curSize: -1,
 	}
 
 	return scaleSet, nil
@@ -190,55 +188,24 @@ func (scaleSet *ScaleSet) IncreaseSize(delta int) error {
 // GetScaleSetVms returns list of nodes for the given scale set.
 // Note that the list results is not used directly because their resource ID format
 // is not consistent with Get results.
-// TODO(feiskyer): use list results directly after the issue fixed in Azure VMSS API.
 func (scaleSet *ScaleSet) GetScaleSetVms() ([]string, error) {
 	ctx, cancel := getContextWithCancel()
 	defer cancel()
 
 	resourceGroup := scaleSet.manager.config.ResourceGroup
-	result, err := scaleSet.manager.azClient.virtualMachineScaleSetVMsClient.List(ctx, resourceGroup, scaleSet.Name, "", "", "")
+	vmList, err := scaleSet.manager.azClient.virtualMachineScaleSetVMsClient.List(ctx, resourceGroup, scaleSet.Name, "", "", "")
 	if err != nil {
 		glog.Errorf("VirtualMachineScaleSetVMsClient.List failed for %s: %v", scaleSet.Name, err)
 		return nil, err
 	}
 
-	instanceIDs := make([]string, 0)
-	for _, vm := range result {
-		instanceIDs = append(instanceIDs, *vm.InstanceID)
-	}
-
 	allVMs := make([]string, 0)
-	for _, instanceID := range instanceIDs {
-		// Get from cache first.
-		if v, ok := scaleSet.virtualMachines[instanceID]; ok {
-			allVMs = append(allVMs, v)
-			continue
-		}
-
-		// Not in cache, get from Azure API.
-		getCtx, getCancel := getContextWithCancel()
-		defer getCancel()
-		vm, err := scaleSet.manager.azClient.virtualMachineScaleSetVMsClient.Get(getCtx, resourceGroup, scaleSet.Name, instanceID)
-		if err != nil {
-			exists, realErr := checkResourceExistsFromError(err)
-			if realErr != nil {
-				glog.Errorf("Failed to get VirtualMachineScaleSetVM by (%s,%s), error: %v", scaleSet.Name, instanceID, err)
-				return nil, realErr
-			}
-
-			if !exists {
-				glog.Warningf("Couldn't find VirtualMachineScaleSetVM by (%s,%s), assuming it has been removed", scaleSet.Name, instanceID)
-				continue
-			}
-		}
-
+	for _, vm := range vmList {
 		// The resource ID is empty string, which indicates the instance may be in deleting state.
 		if len(*vm.ID) == 0 {
 			continue
 		}
 
-		// Save into cache.
-		scaleSet.virtualMachines[instanceID] = *vm.ID
 		allVMs = append(allVMs, *vm.ID)
 	}
 
@@ -288,7 +255,7 @@ func (scaleSet *ScaleSet) Belongs(node *apiv1.Node) (bool, error) {
 	if targetAsg == nil {
 		return false, fmt.Errorf("%s doesn't belong to a known scale set", node.Name)
 	}
-	if targetAsg.Id() != scaleSet.Id() {
+	if !strings.EqualFold(targetAsg.Id(), scaleSet.Id()) {
 		return false, nil
 	}
 	return true, nil
@@ -314,7 +281,7 @@ func (scaleSet *ScaleSet) DeleteInstances(instances []*azureRef) error {
 			return err
 		}
 
-		if asg != commonAsg {
+		if !strings.EqualFold(asg.Id(), commonAsg.Id()) {
 			return fmt.Errorf("cannot delete instance (%s) which don't belong to the same Scale Set (%q)", instance.Name, commonAsg)
 		}
 
@@ -468,7 +435,7 @@ func (scaleSet *ScaleSet) Nodes() ([]string, error) {
 
 	result := make([]string, 0, len(vms))
 	for i := range vms {
-		name := "azure://" + vms[i]
+		name := "azure://" + strings.ToLower(vms[i])
 		result = append(result, name)
 	}
 
diff --git a/cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go b/cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go
index 92c06a4a9fec47b24b7fcf570cbd8f8b5fc85fd4..a2cfc2fc54a9adbc83d8585e9a3abc1cc6a920b4 100644
--- a/cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go
+++ b/cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go
@@ -33,10 +33,9 @@ func newTestScaleSet(manager *AzureManager, name string) *ScaleSet {
 		azureRef: azureRef{
 			Name: name,
 		},
-		manager:         manager,
-		minSize:         1,
-		maxSize:         5,
-		virtualMachines: make(map[string]string),
+		manager: manager,
+		minSize: 1,
+		maxSize: 5,
 	}
 }
 
@@ -92,7 +91,7 @@ func TestBelongs(t *testing.T) {
 
 	invalidNode := &apiv1.Node{
 		Spec: apiv1.NodeSpec{
-			ProviderID: "azure:///subscriptions/test-subscrition-id/resourceGroups/invalid-asg/providers/Microsoft.Compute/virtualMachineScaleSets/agents/virtualMachines/0",
+			ProviderID: "azure:///subscriptions/test-subscrition-id/resourcegroups/invalid-asg/providers/microsoft.compute/virtualmachinescalesets/agents/virtualmachines/0",
 		},
 	}
 	_, err := scaleSet.Belongs(invalidNode)
@@ -183,10 +182,6 @@ func TestScaleSetNodes(t *testing.T) {
 	ss, ok := group.(*ScaleSet)
 	assert.True(t, ok)
 	assert.NotNil(t, ss)
-	assert.Equal(t, ss.virtualMachines, map[string]string{
-		"0": fakeVirtualMachineScaleSetVMID,
-	})
-
 	instances, err := group.Nodes()
 	assert.NoError(t, err)
 	assert.Equal(t, len(instances), 1)
diff --git a/cluster-autoscaler/cloudprovider/cloud_provider.go b/cluster-autoscaler/cloudprovider/cloud_provider.go
index e8494698a7cd0efc7c1a688751a8c7c0601b2b3a..8cdd485e3b226fa133de76883b2191dfaa793afc 100644
--- a/cluster-autoscaler/cloudprovider/cloud_provider.go
+++ b/cluster-autoscaler/cloudprovider/cloud_provider.go
@@ -58,6 +58,9 @@ type CloudProvider interface {
 	// GetResourceLimiter returns struct containing limits (max, min) for resources (cores, memory etc.).
 	GetResourceLimiter() (*ResourceLimiter, error)
 
+	// GetInstanceID gets the instance ID for the specified node.
+	GetInstanceID(node *apiv1.Node) string
+
 	// Cleanup cleans up open resources before the cloud provider is destroyed, i.e. go routines etc.
 	Cleanup() error
 
diff --git a/cluster-autoscaler/cloudprovider/gce/gce_cloud_provider.go b/cluster-autoscaler/cloudprovider/gce/gce_cloud_provider.go
index bc9f48549ffa4419b364ad8743769d09564608e9..6144d9c07fc2cccffe9468daa140629b0d2ff958 100644
--- a/cluster-autoscaler/cloudprovider/gce/gce_cloud_provider.go
+++ b/cluster-autoscaler/cloudprovider/gce/gce_cloud_provider.go
@@ -197,7 +197,12 @@ func (gce *GceCloudProvider) Refresh() error {
 	return gce.gceManager.Refresh()
 }
 
-// GceRef contains s reference to some entity in GCE/GKE world.
+// GetInstanceID gets the instance ID for the specified node.
+func (gce *GceCloudProvider) GetInstanceID(node *apiv1.Node) string {
+	return node.Spec.ProviderID
+}
+
+// GceRef contains s reference to some entity in GCE world.
 type GceRef struct {
 	Project string
 	Zone    string
diff --git a/cluster-autoscaler/cloudprovider/gce/gce_manager.go b/cluster-autoscaler/cloudprovider/gce/gce_manager.go
index 4a37fb07bc5ed851dade6f4eb04d8432bc12f938..d7dc3585e47c61cbf363fbd76fe6fc9928586306 100644
--- a/cluster-autoscaler/cloudprovider/gce/gce_manager.go
+++ b/cluster-autoscaler/cloudprovider/gce/gce_manager.go
@@ -1017,7 +1017,7 @@ func (m *gceManagerImpl) fetchResourceLimiter() error {
 		maxLimits := make(map[string]int64)
 		for _, limit := range cluster.Autoscaling.ResourceLimits {
 			if _, found := supportedResources[limit.Name]; !found {
-				glog.Warning("Unsupported limit defined %s: %d - %d", limit.Name, limit.Minimum, limit.Maximum)
+				glog.Warningf("Unsupported limit defined %s: %d - %d", limit.Name, limit.Minimum, limit.Maximum)
 			}
 			minLimits[limit.Name] = limit.Minimum
 			maxLimits[limit.Name] = limit.Maximum
diff --git a/cluster-autoscaler/cloudprovider/kubemark/kubemark_linux.go b/cluster-autoscaler/cloudprovider/kubemark/kubemark_linux.go
index fca795cb1b264aa8dcaf8419366e3ff300d2884f..32a3133bda5eeb2f838ed08219c0fbf5428f8e80 100644
--- a/cluster-autoscaler/cloudprovider/kubemark/kubemark_linux.go
+++ b/cluster-autoscaler/cloudprovider/kubemark/kubemark_linux.go
@@ -129,6 +129,11 @@ func (kubemark *KubemarkCloudProvider) Refresh() error {
 	return nil
 }
 
+// GetInstanceID gets the instance ID for the specified node.
+func (kubemark *KubemarkCloudProvider) GetInstanceID(node *apiv1.Node) string {
+	return node.Spec.ProviderID
+}
+
 // Cleanup cleans up all resources before the cloud provider is removed
 func (kubemark *KubemarkCloudProvider) Cleanup() error {
 	return nil
diff --git a/cluster-autoscaler/cloudprovider/kubemark/kubemark_other.go b/cluster-autoscaler/cloudprovider/kubemark/kubemark_other.go
index 5b0182fb3ee07ecb67f45f863975e4960962e227..29b16f71bffaae04a58e6fd718cbc32a2acadff4 100644
--- a/cluster-autoscaler/cloudprovider/kubemark/kubemark_other.go
+++ b/cluster-autoscaler/cloudprovider/kubemark/kubemark_other.go
@@ -72,6 +72,11 @@ func (kubemark *KubemarkCloudProvider) Refresh() error {
 	return cloudprovider.ErrNotImplemented
 }
 
+// GetInstanceID gets the instance ID for the specified node.
+func (kubemark *KubemarkCloudProvider) GetInstanceID(node *apiv1.Node) string {
+	return ""
+}
+
 // Cleanup cleans up all resources before the cloud provider is removed
 func (kubemark *KubemarkCloudProvider) Cleanup() error {
 	return cloudprovider.ErrNotImplemented
diff --git a/cluster-autoscaler/cloudprovider/test/test_cloud_provider.go b/cluster-autoscaler/cloudprovider/test/test_cloud_provider.go
index 488d220d30ff302dcce6a98b2b359929a34c4744..1147db1a9922804f216ce6a15c10d318c64b504b 100644
--- a/cluster-autoscaler/cloudprovider/test/test_cloud_provider.go
+++ b/cluster-autoscaler/cloudprovider/test/test_cloud_provider.go
@@ -211,6 +211,11 @@ func (tcp *TestCloudProvider) Refresh() error {
 	return nil
 }
 
+// GetInstanceID gets the instance ID for the specified node.
+func (tcp *TestCloudProvider) GetInstanceID(node *apiv1.Node) string {
+	return node.Spec.ProviderID
+}
+
 // TestNodeGroup is a node group used by TestCloudProvider.
 type TestNodeGroup struct {
 	sync.Mutex
diff --git a/cluster-autoscaler/clusterstate/clusterstate.go b/cluster-autoscaler/clusterstate/clusterstate.go
index fb01c64a90f89dc6d3c38c2fda0d3b438eaa0bdc..39ebc581dfd8f5d6217aa5ef25dc1f1a90c2318c 100644
--- a/cluster-autoscaler/clusterstate/clusterstate.go
+++ b/cluster-autoscaler/clusterstate/clusterstate.go
@@ -894,7 +894,7 @@ func (csr *ClusterStateRegistry) GetUpcomingNodes() map[string]int {
 func getNotRegisteredNodes(allNodes []*apiv1.Node, cloudProvider cloudprovider.CloudProvider, time time.Time) ([]UnregisteredNode, error) {
 	registered := sets.NewString()
 	for _, node := range allNodes {
-		registered.Insert(node.Spec.ProviderID)
+		registered.Insert(cloudProvider.GetInstanceID(node))
 	}
 	notRegistered := make([]UnregisteredNode, 0)
 	for _, nodeGroup := range cloudProvider.NodeGroups() {